diff options
| -rw-r--r-- | include/gui/SurfaceTextureClient.h | 5 | ||||
| -rw-r--r-- | libs/gui/SurfaceTextureClient.cpp | 43 | ||||
| -rw-r--r-- | libs/ui/FramebufferNativeWindow.cpp | 1 | ||||
| -rw-r--r-- | libs/utils/VectorImpl.cpp | 4 | ||||
| -rw-r--r-- | opengl/libs/EGL/egl.cpp | 5 | ||||
| -rw-r--r-- | opengl/libs/EGL/eglApi.cpp | 7 | ||||
| -rw-r--r-- | opengl/specs/EGL_ANDROID_blob_cache.txt | 208 | ||||
| -rw-r--r-- | opengl/specs/EGL_ANDROID_recordable.txt | 113 | ||||
| -rw-r--r-- | opengl/specs/README | 12 |
9 files changed, 389 insertions, 9 deletions
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h index 6ce44fcac7..9db7364242 100644 --- a/include/gui/SurfaceTextureClient.h +++ b/include/gui/SurfaceTextureClient.h @@ -65,6 +65,8 @@ private: int dispatchDisconnect(va_list args); int dispatchSetBufferCount(va_list args); int dispatchSetBuffersGeometry(va_list args); + int dispatchSetBuffersDimensions(va_list args); + int dispatchSetBuffersFormat(va_list args); int dispatchSetBuffersTransform(va_list args); int dispatchSetBuffersTimestamp(va_list args); int dispatchSetCrop(va_list args); @@ -73,7 +75,8 @@ private: int connect(int api); int disconnect(int api); int setBufferCount(int bufferCount); - int setBuffersGeometry(int w, int h, int format); + int setBuffersDimensions(int w, int h); + int setBuffersFormat(int format); int setBuffersTransform(int transform); int setBuffersTimestamp(int64_t timestamp); int setCrop(Rect const* rect); diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp index b9b2310c7f..e203035ee9 100644 --- a/libs/gui/SurfaceTextureClient.cpp +++ b/libs/gui/SurfaceTextureClient.cpp @@ -254,6 +254,12 @@ int SurfaceTextureClient::perform(int operation, va_list args) case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP: res = dispatchSetBuffersTimestamp(args); break; + case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS: + res = dispatchSetBuffersDimensions(args); + break; + case NATIVE_WINDOW_SET_BUFFERS_FORMAT: + res = dispatchSetBuffersFormat(args); + break; default: res = NAME_NOT_FOUND; break; @@ -290,7 +296,22 @@ int SurfaceTextureClient::dispatchSetBuffersGeometry(va_list args) { int w = va_arg(args, int); int h = va_arg(args, int); int f = va_arg(args, int); - return setBuffersGeometry(w, h, f); + int err = setBuffersDimensions(w, h); + if (err != 0) { + return err; + } + return setBuffersFormat(f); +} + +int SurfaceTextureClient::dispatchSetBuffersDimensions(va_list args) { + int w = va_arg(args, int); + int h = va_arg(args, int); + return setBuffersDimensions(w, h); +} + +int SurfaceTextureClient::dispatchSetBuffersFormat(va_list args) { + int f = va_arg(args, int); + return setBuffersFormat(f); } int SurfaceTextureClient::dispatchSetBuffersTransform(va_list args) { @@ -390,12 +411,12 @@ int SurfaceTextureClient::setBufferCount(int bufferCount) return err; } -int SurfaceTextureClient::setBuffersGeometry(int w, int h, int format) +int SurfaceTextureClient::setBuffersDimensions(int w, int h) { - LOGV("SurfaceTextureClient::setBuffersGeometry"); + LOGV("SurfaceTextureClient::setBuffersDimensions"); Mutex::Autolock lock(mMutex); - if (w<0 || h<0 || format<0) + if (w<0 || h<0) return BAD_VALUE; if ((w && !h) || (!w && h)) @@ -403,7 +424,6 @@ int SurfaceTextureClient::setBuffersGeometry(int w, int h, int format) mReqWidth = w; mReqHeight = h; - mReqFormat = format; status_t err = mSurfaceTexture->setCrop(Rect(0, 0)); LOGE_IF(err, "ISurfaceTexture::setCrop(...) returned %s", strerror(-err)); @@ -411,6 +431,19 @@ int SurfaceTextureClient::setBuffersGeometry(int w, int h, int format) return err; } +int SurfaceTextureClient::setBuffersFormat(int format) +{ + LOGV("SurfaceTextureClient::setBuffersFormat"); + Mutex::Autolock lock(mMutex); + + if (format<0) + return BAD_VALUE; + + mReqFormat = format; + + return NO_ERROR; +} + int SurfaceTextureClient::setBuffersTransform(int transform) { LOGV("SurfaceTextureClient::setBuffersTransform"); diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp index 4393504236..9c10c754ba 100644 --- a/libs/ui/FramebufferNativeWindow.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -299,6 +299,7 @@ int FramebufferNativeWindow::perform(ANativeWindow* window, { switch (operation) { case NATIVE_WINDOW_SET_USAGE: + case NATIVE_WINDOW_SET_BUFFERS_FORMAT: case NATIVE_WINDOW_CONNECT: case NATIVE_WINDOW_DISCONNECT: break; diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp index 289c826d3e..87ae3d51f1 100644 --- a/libs/utils/VectorImpl.cpp +++ b/libs/utils/VectorImpl.cpp @@ -290,7 +290,7 @@ void VectorImpl::clear() void* VectorImpl::editItemLocation(size_t index) { LOG_ASSERT(index<capacity(), - "[%p] itemLocation: index=%d, capacity=%d, count=%d", + "[%p] editItemLocation: index=%d, capacity=%d, count=%d", this, (int)index, (int)capacity(), (int)mCount); void* buffer = editArrayImpl(); @@ -302,7 +302,7 @@ void* VectorImpl::editItemLocation(size_t index) const void* VectorImpl::itemLocation(size_t index) const { LOG_ASSERT(index<capacity(), - "[%p] editItemLocation: index=%d, capacity=%d, count=%d", + "[%p] itemLocation: index=%d, capacity=%d, count=%d", this, (int)index, (int)capacity(), (int)mCount); const void* buffer = arrayImpl(); diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index b11db324dd..ddad2d323f 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -31,6 +31,7 @@ #include <cutils/properties.h> #include <cutils/memory.h> +#include <utils/CallStack.h> #include <utils/String8.h> #include "egldefs.h" @@ -147,6 +148,10 @@ static int gl_no_context() { if (egl_tls_t::logNoContextCall()) { LOGE("call to OpenGL ES API with no current context " "(logged once per thread)"); + LOGE("call stack before error:"); + CallStack stack; + stack.update(); + stack.dump(); } return 0; } diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index 7d5d01084f..ba5d29a17d 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -367,7 +367,12 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, if (cnx->egl.eglGetConfigAttrib(iDpy, iConfig, EGL_NATIVE_VISUAL_ID, &format)) { if (format != 0) { - native_window_set_buffers_geometry(window, 0, 0, format); + int err = native_window_set_buffers_format(window, format); + if (err != 0) { + LOGE("error setting native window pixel format: %s (%d)", + strerror(-err), err); + return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); + } } } diff --git a/opengl/specs/EGL_ANDROID_blob_cache.txt b/opengl/specs/EGL_ANDROID_blob_cache.txt new file mode 100644 index 0000000000..55dc9004a1 --- /dev/null +++ b/opengl/specs/EGL_ANDROID_blob_cache.txt @@ -0,0 +1,208 @@ +Name + + ANDROID_blob_cache + +Name Strings + + EGL_ANDROID_blob_cache + +Contributors + + Jamie Gennis + +Contact + + Jamie Gennis, Google Inc. (jgennis 'at' google.com) + +Status + + Draft. + +Version + + Version 1, April 22, 2011 + +Number + + EGL Extension #XXX + +Dependencies + + Requires EGL 1.0 + + This extension is written against the wording of the EGL 1.4 Specification + +Overview + + Shader compilation and optimization has been a troublesome aspect of OpenGL + programming for a long time. It can consume seconds of CPU cycles during + application start-up. Additionally, state-based re-compiles done + internally by the drivers add an unpredictable element to application + performance tuning, often leading to occasional pauses in otherwise smooth + animations. + + This extension provides a mechanism through which client API + implementations may cache shader binaries after they are compiled. It may + then retrieve those cached shaders during subsequent executions of the same + program. The management of the cache is handled by the application (or + middleware), allowing it to be tuned to a particular platform or + environment. + + While the focus of this extension is on providing a persistent cache for + shader binaries, it may also be useful for caching other data. This is + perfectly acceptable, but the guarantees provided (or lack thereof) were + designed around the shader use case. + + Note that although this extension is written as if the application + implements the caching functionality, on the Android OS it is implemented + as part of the Android EGL module. This extension is not exposed to + applications on Android, but will be used automatically in every + application that uses EGL if it is supported by the underlying + device-specific EGL implementation. + +New Types + + /* + * EGLsizei is a signed integer type for representing the size of a memory + * buffer. + */ + #include <khrplatform.h> + typedef khronos_ssize_t EGLsizei; + + /* + * EGLSetBlobFunc is a pointer to an application-provided function that a + * client API implementation may use to insert a key/value pair into the + * cache. + */ + typedef void (*EGLSetBlobFunc) (const void* key, EGLsizei keySize, + const void* value, EGLsizei valueSize) + + /* + * EGLGetBlobFunc is a pointer to an application-provided function that a + * client API implementation may use to retrieve a cached value from the + * cache. + */ + typedef EGLsizei (*EGLGetBlobFunc) (const void* key, EGLsizei keySize, + void* value, EGLsizei valueSize) + +New Procedures and Functions + + void eglSetBlobCacheFuncs(EGLDisplay dpy, + EGLSetBlobFunc set, + EGLGetBlobFunc get); + +New Tokens + + None. + +Changes to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors) + + Add a new subsection after Section 3.8, page 50 + (Synchronization Primitives) + + "3.9 Persistent Caching + + In order to facilitate persistent caching of internal client API state that + is slow to compute or collect, the application may specify callback + function pointers through which the client APIs can request data be cached + and retrieved. The command + + void eglSetBlobCacheFuncs(EGLDisplay dpy, + EGLSetBlobFunc set, EGLGetBlobFunc get); + + sets the callback function pointers that client APIs associated with + display <dpy> can use to interact with caching functionality provided by + the application. <set> points to a function that inserts a new value into + the cache and associates it with the given key. <get> points to a function + that retrieves from the cache the value associated with a given key. The + semantics of these callback functions are described in Section 3.9.1 (Cache + Operations). + + Cache functions may only be specified once during the lifetime of an + EGLDisplay. The <set> and <get> functions may be called at any time and + from any thread from the time at which eglSetBlobCacheFuncs is called until + the time that the last resource associated with <dpy> is deleted and <dpy> + itself is terminated. Concurrent calls to these functions from different + threads is also allowed. + + If eglSetBlobCacheFuncs generates an error then all client APIs must behave + as though eglSetBlobCacheFuncs was not called for the display <dpy>. If + <set> or <get> is NULL then an EGL_BAD_PARAMETER error is generated. If a + successful eglSetBlobCacheFuncs call was already made for <dpy> and the + display has not since been terminated then an EGL_BAD_PARAMETER error is + generated. + + 3.9.1 Cache Operations + + To insert a new binary value into the cache and associate it with a given + key, a client API implementation can call the application-provided callback + function + + void (*set) (const void* key, EGLsizei keySize, const void* value, + EGLsizei valueSize) + + <key> and <value> are pointers to the beginning of the key and value, + respectively, that are to be inserted. <keySize> and <valueSize> specify + the size in bytes of the data pointed to by <key> and <value>, + respectively. + + No guarantees are made as to whether a given key/value pair is present in + the cache after the set call. If a different value has been associated + with the given key in the past then it is undefined which value, if any, is + associated with the key after the set call. Note that while there are no + guarantees, the cache implementation should attempt to cache the most + recently set value for a given key. + + To retrieve the binary value associated with a given key from the cache, a + client API implementation can call the application-provided callback + function + + EGLsizei (*get) (const void* key, EGLsizei keySize, void* value, + EGLsizei valueSize) + + <key> is a pointer to the beginning of the key. <keySize> specifies the + size in bytes of the binary key pointed to by <key>. If the cache contains + a value associated with the given key then the size of that binary value in + bytes is returned. Otherwise 0 is returned. + + If the cache contains a value for the given key and its size in bytes is + less than or equal to <valueSize> then the value is written to the memory + pointed to by <value>. Otherwise nothing is written to the memory pointed + to by <value>. + +Issues + + 1. How should errors be handled in the callback functions? + + RESOLVED: No guarantees are made about the presence of values in the cache, + so there should not be a need to return error information to the client API + implementation. The cache implementation can simply drop a value if it + encounters an error during the 'set' callback. Similarly, it can simply + return 0 if it encouters an error in a 'get' callback. + + 2. When a client API driver gets updated, that may need to invalidate + previously cached entries. How can the driver handle this situation? + + RESPONSE: There are a number of ways the driver can handle this situation. + The recommended way is to include the driver version in all cache keys. + That way each driver version will use a set of cache keys that are unique + to that version, and conflicts should never occur. Updating the driver + could then leave a number of values in the cache that will never be + requested again. If needed, the cache implementation can handle those + values in some way, but the driver does not need to take any special + action. + + 3. How much data can be stored in the cache? + + RESPONSE: This is entirely dependent upon the cache implementation. + Presumably it will be tuned to store enough data to be useful, but not + enough to become problematic. :) + +Revision History + +#2 (Jamie Gennis, April 25, 2011) + - Swapped the order of the size and pointer arguments to the get and set + functions. + +#1 (Jamie Gennis, April 22, 2011) + - Initial draft. diff --git a/opengl/specs/EGL_ANDROID_recordable.txt b/opengl/specs/EGL_ANDROID_recordable.txt new file mode 100644 index 0000000000..cf44465198 --- /dev/null +++ b/opengl/specs/EGL_ANDROID_recordable.txt @@ -0,0 +1,113 @@ +Name + + ANDROID_recordable + +Name Strings + + EGL_ANDROID_recordable + +Contributors + + Jamie Gennis + +Contact + + Jamie Gennis, Google Inc. (jgennis 'at' google.com) + +Status + + Draft. + +Version + + Version 1, July 8, 2011 + +Number + + EGL Extension #XXX + +Dependencies + + Requires EGL 1.0 + + This extension is written against the wording of the EGL 1.4 Specification + +Overview + + Android supports a number of different ANativeWindow implementations that + can be used to create an EGLSurface. One implementation, which records the + rendered image as a video each time eglSwapBuffers gets called, may have + some device-specific restrictions. Because of this, some EGLConfigs may be + incompatible with these ANativeWindows. This extension introduces a new + boolean EGLConfig attribute that indicates whether the EGLConfig supports + rendering to an ANativeWindow that records images to a video. + +New Types + + None. + +New Procedures and Functions + + None. + +New Tokens + + Accepted by the <attribute> parameter of eglGetConfigAttrib and + the <attrib_list> parameter of eglChooseConfig: + + EGL_RECORDABLE_ANDROID 0xXXXX + +Changes to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors) + + Section 3.4, Configuration Management, add a row to Table 3.1. + + Attribute Type Notes + ---------------------- ------- -------------------------- + EGL_RECORDABLE_ANDROID boolean whether video recording is + supported + + Section 3.4, Configuration Management, add a row to Table 3.4. + + Attribute Default Selection Sort Sort + Criteria Order Priority + ---------------------- ------------- --------- ----- -------- + EGL_RECORDABLE_ANDROID EGL_DONT_CARE Exact None + + Section 3.4, Configuration Management, add a paragraph at the end of the + subsection titled Other EGLConfig Attribute Descriptions. + + EGL_RECORDABLE_ANDROID is a boolean indicating whether the config may + be used to create an EGLSurface from an ANativeWindow that is a video + recorder as indicated by the NATIVE_WINDOW_IS_VIDEO_RECORDER query on + the ANativeWindow. + + Section 3.4.1, Querying Configurations, change the last paragraph as follow + + EGLConfigs are not sorted with respect to the parameters + EGL_BIND_TO_TEXTURE_RGB, EGL_BIND_TO_TEXTURE_RGBA, EGL_CONFORMANT, + EGL_LEVEL, EGL_NATIVE_RENDERABLE, EGL_MAX_SWAP_INTERVAL, + EGL_MIN_SWAP_INTERVAL, EGL_RENDERABLE_TYPE, EGL_SURFACE_TYPE, + EGL_TRANSPARENT_TYPE, EGL_TRANSPARENT_RED_VALUE, + EGL_TRANSPARENT_GREEN_VALUE, EGL_TRANSPARENT_BLUE_VALUE, and + EGL_RECORDABLE_ANDROID. + +Issues + + 1. Should this functionality be exposed as a new attribute or as a bit in + the EGL_SURFACE_TYPE bitfield? + + RESOLVED: It should be a new attribute. It does not make sense to use up a + bit in the limit-size bitfield for a platform-specific extension. + + 2. How should the new attribute affect the sorting of EGLConfigs? + + RESOLVED: It should not affect sorting. Some implementations may not have + any drawback associated with using a recordable EGLConfig. Such + implementations should not have to double-up some of their configs to one sort earlier than . + Implementations that do have drawbacks can use the existing caveat + mechanism to report this drawback to the client. + +Revision History + +#1 (Jamie Gennis, July 8, 2011) + - Initial draft. diff --git a/opengl/specs/README b/opengl/specs/README new file mode 100644 index 0000000000..2fa258777f --- /dev/null +++ b/opengl/specs/README @@ -0,0 +1,12 @@ +This directory contains OpenGL ES and EGL extension specifications that have +been or are being defined for Android. + +The table below tracks usage of EGL enumerant values that have been reserved +for use by Android extensions. + + Value Extension +---------------- ---------------------------------- +0x3140 EGL_ANDROID_image_native_buffer +0x3141 (unused) +0x3142 EGL_ANDROID_recordable +0x3143 - 0x314F (unused) |