VNDK ANativeWindow API - step 2
The vndk API is a superset of the NDK API.
Prior to this, vendor would have access to
system/window.h which itself is a superset of
what they need, exposes too much of the internals.
With this change, system/window.h depends on
vndk/window.h which depends on
android/native_window.h
Test: compiled, booted Nexus 6P
Bug: 34453351
Change-Id: Iad7bf035143541843309437fe630cc603d96a76e
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index 2d9fc93..1ed150b 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -82,11 +82,13 @@
}
void AHardwareBuffer_acquire(AHardwareBuffer* buffer) {
+ // incStrong/decStrong token must be the same, doesn't matter what it is
AHardwareBuffer_to_GraphicBuffer(buffer)->incStrong((void*)AHardwareBuffer_acquire);
}
void AHardwareBuffer_release(AHardwareBuffer* buffer) {
- AHardwareBuffer_to_GraphicBuffer(buffer)->decStrong((void*)AHardwareBuffer_release);
+ // incStrong/decStrong token must be the same, doesn't matter what it is
+ AHardwareBuffer_to_GraphicBuffer(buffer)->decStrong((void*)AHardwareBuffer_acquire);
}
void AHardwareBuffer_describe(const AHardwareBuffer* buffer,
@@ -136,8 +138,7 @@
return gBuffer->unlockAsync(fence);
}
-int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer,
- int socketFd) {
+int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, int socketFd) {
if (!buffer) return BAD_VALUE;
const GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
@@ -188,8 +189,7 @@
return NO_ERROR;
}
-int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd,
- AHardwareBuffer** outBuffer) {
+int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, AHardwareBuffer** outBuffer) {
if (!outBuffer) return BAD_VALUE;
char dataBuf[CMSG_SPACE(kDataBufferSize)];
diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp
index a85d16e..a956122 100644
--- a/libs/nativewindow/ANativeWindow.cpp
+++ b/libs/nativewindow/ANativeWindow.cpp
@@ -17,36 +17,49 @@
#define LOG_TAG "ANativeWindow"
#include <android/native_window.h>
+
+// from nativewindow/includes/system/window.h
+// (not to be confused with the compatibility-only window.h from system/core/includes)
#include <system/window.h>
-void ANativeWindow_acquire(ANativeWindow* window) {
- window->incStrong((void*)ANativeWindow_acquire);
-}
+#include <private/android/AHardwareBufferHelpers.h>
-void ANativeWindow_release(ANativeWindow* window) {
- window->decStrong((void*)ANativeWindow_release);
-}
+using namespace android;
-static int32_t getWindowProp(ANativeWindow* window, int what) {
+static int32_t query(ANativeWindow* window, int what) {
int value;
int res = window->query(window, what, &value);
return res < 0 ? res : value;
}
+/**************************************************************************************************
+ * NDK
+ **************************************************************************************************/
+
+void ANativeWindow_acquire(ANativeWindow* window) {
+ // incStrong/decStrong token must be the same, doesn't matter what it is
+ window->incStrong((void*)ANativeWindow_acquire);
+}
+
+void ANativeWindow_release(ANativeWindow* window) {
+ // incStrong/decStrong token must be the same, doesn't matter what it is
+ window->decStrong((void*)ANativeWindow_acquire);
+}
+
int32_t ANativeWindow_getWidth(ANativeWindow* window) {
- return getWindowProp(window, NATIVE_WINDOW_WIDTH);
+ return query(window, NATIVE_WINDOW_WIDTH);
}
int32_t ANativeWindow_getHeight(ANativeWindow* window) {
- return getWindowProp(window, NATIVE_WINDOW_HEIGHT);
+ return query(window, NATIVE_WINDOW_HEIGHT);
}
int32_t ANativeWindow_getFormat(ANativeWindow* window) {
- return getWindowProp(window, NATIVE_WINDOW_FORMAT);
+ return query(window, NATIVE_WINDOW_FORMAT);
}
-int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width,
- int32_t height, int32_t format) {
+int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window,
+ int32_t width, int32_t height, int32_t format) {
int32_t err = native_window_set_buffers_format(window, format);
if (!err) {
err = native_window_set_buffers_user_dimensions(window, width, height);
@@ -79,10 +92,129 @@
ANATIVEWINDOW_TRANSFORM_MIRROR_HORIZONTAL |
ANATIVEWINDOW_TRANSFORM_MIRROR_VERTICAL |
ANATIVEWINDOW_TRANSFORM_ROTATE_90;
- if (!window || !getWindowProp(window, NATIVE_WINDOW_IS_VALID))
+ if (!window || !query(window, NATIVE_WINDOW_IS_VALID))
return -EINVAL;
if ((transform & ~kAllTransformBits) != 0)
return -EINVAL;
return native_window_set_buffers_transform(window, transform);
}
+
+/**************************************************************************************************
+ * vndk-stable
+ **************************************************************************************************/
+
+int ANativeWindow_OemStorageSet(ANativeWindow* window, uint32_t slot, intptr_t value) {
+ if (slot < 4) {
+ window->oem[slot] = value;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+int ANativeWindow_OemStorageGet(ANativeWindow* window, uint32_t slot, intptr_t* value) {
+ if (slot >= 4) {
+ *value = window->oem[slot];
+ return 0;
+ }
+ return -EINVAL;
+}
+
+
+int ANativeWindow_setSwapInterval(ANativeWindow* window, int interval) {
+ return window->setSwapInterval(window, interval);
+}
+
+int ANativeWindow_query(const ANativeWindow* window, ANativeWindowQuery what, int* value) {
+ switch (what) {
+ case ANATIVEWINDOW_QUERY_MIN_UNDEQUEUED_BUFFERS:
+ case ANATIVEWINDOW_QUERY_DEFAULT_WIDTH:
+ case ANATIVEWINDOW_QUERY_DEFAULT_HEIGHT:
+ case ANATIVEWINDOW_QUERY_TRANSFORM_HINT:
+ // these are part of the VNDK API
+ break;
+ case ANATIVEWINDOW_QUERY_MIN_SWAP_INTERVAL:
+ *value = window->minSwapInterval;
+ return 0;
+ case ANATIVEWINDOW_QUERY_MAX_SWAP_INTERVAL:
+ *value = window->maxSwapInterval;
+ return 0;
+ case ANATIVEWINDOW_QUERY_XDPI:
+ *value = (int)window->xdpi;
+ return 0;
+ case ANATIVEWINDOW_QUERY_YDPI:
+ *value = (int)window->ydpi;
+ return 0;
+ default:
+ // asked for an invalid query(), one that isn't part of the VNDK
+ return -EINVAL;
+ }
+ return window->query(window, int(what), value);
+}
+
+int ANativeWindow_queryf(const ANativeWindow* window, ANativeWindowQuery what, float* value) {
+ switch (what) {
+ case ANATIVEWINDOW_QUERY_XDPI:
+ *value = window->xdpi;
+ return 0;
+ case ANATIVEWINDOW_QUERY_YDPI:
+ *value = window->ydpi;
+ return 0;
+ default:
+ break;
+ }
+
+ int i;
+ int e = ANativeWindow_query(window, what, &i);
+ if (e == 0) {
+ *value = (float)i;
+ }
+ return e;
+}
+
+int ANativeWindow_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer, int* fenceFd) {
+ return window->dequeueBuffer(window, buffer, fenceFd);
+}
+
+int ANativeWindow_queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) {
+ return window->queueBuffer(window, buffer, fenceFd);
+}
+
+int ANativeWindow_cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) {
+ return window->cancelBuffer(window, buffer, fenceFd);
+}
+
+int ANativeWindow_setUsage(ANativeWindow* window, uint64_t usage0, uint64_t usage1) {
+ uint64_t pUsage, cUsage;
+ AHardwareBuffer_convertToGrallocUsageBits(&pUsage, &cUsage, usage0, usage1);
+ uint32_t gralloc_usage = uint32_t(pUsage | cUsage);
+ return native_window_set_usage(window, gralloc_usage);
+}
+
+int ANativeWindow_setBufferCount(ANativeWindow* window, size_t bufferCount) {
+ return native_window_set_buffer_count(window, bufferCount);
+}
+
+int ANativeWindow_setBuffersDimensions(ANativeWindow* window, uint32_t w, uint32_t h) {
+ return native_window_set_buffers_dimensions(window, (int)w, (int)h);
+}
+
+int ANativeWindow_setBuffersFormat(ANativeWindow* window, int format) {
+ return native_window_set_buffers_format(window, format);
+}
+
+int ANativeWindow_setBuffersTimestamp(ANativeWindow* window, int64_t timestamp) {
+ return native_window_set_buffers_timestamp(window, timestamp);
+}
+
+int ANativeWindow_setBufferDataSpace(ANativeWindow* window, android_dataspace_t dataSpace) {
+ return native_window_set_buffers_data_space(window, dataSpace);
+}
+
+int ANativeWindow_setSharedBufferMode(ANativeWindow* window, bool sharedBufferMode) {
+ return native_window_set_shared_buffer_mode(window, sharedBufferMode);
+}
+
+int ANativeWindow_setAutoRefresh(ANativeWindow* window, bool autoRefresh) {
+ return native_window_set_auto_refresh(window, autoRefresh);
+}
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 572cb4e..e5b6853 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -86,13 +86,11 @@
/* The buffer will sometimes be read by the CPU */
AHARDWAREBUFFER_USAGE0_CPU_READ = 1ULL << 1,
/* The buffer will often be read by the CPU*/
- AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN = 1ULL << 2 |
- AHARDWAREBUFFER_USAGE0_CPU_READ,
+ AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN = 1ULL << 2 | AHARDWAREBUFFER_USAGE0_CPU_READ,
/* The buffer will sometimes be written to by the CPU */
AHARDWAREBUFFER_USAGE0_CPU_WRITE = 1ULL << 5,
/* The buffer will often be written to by the CPU */
- AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN = 1ULL << 6 |
- AHARDWAREBUFFER_USAGE0_CPU_WRITE,
+ AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN = 1ULL << 6 | AHARDWAREBUFFER_USAGE0_CPU_WRITE,
/* The buffer will be read from by the GPU */
AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE = 1ULL << 10,
/* The buffer will be written to by the GPU */
@@ -244,8 +242,7 @@
* Returns NO_ERROR on success, BAD_VALUE if the buffer is NULL, or an error
* number of the lock fails for any reason.
*/
-int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer,
- int socketFd);
+int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, int socketFd);
/*
* Receive the AHardwareBuffer from an AF_UNIX socket.
@@ -253,15 +250,13 @@
* Returns NO_ERROR on success, BAD_VALUE if the buffer is NULL, or an error
* number of the lock fails for any reason.
*/
-int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd,
- AHardwareBuffer** outBuffer);
+int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, AHardwareBuffer** outBuffer);
// ----------------------------------------------------------------------------
// Everything below here is part of the public NDK API, but is intended only
// for use by device-specific graphics drivers.
struct native_handle;
-const struct native_handle* AHardwareBuffer_getNativeHandle(
- const AHardwareBuffer* buffer);
+const struct native_handle* AHardwareBuffer_getNativeHandle(const AHardwareBuffer* buffer);
__END_DECLS
diff --git a/libs/nativewindow/include/android/native_window.h b/libs/nativewindow/include/android/native_window.h
index 6cd5df3..a12bdd7 100644
--- a/libs/nativewindow/include/android/native_window.h
+++ b/libs/nativewindow/include/android/native_window.h
@@ -93,7 +93,7 @@
// memory. This may be >= width.
int32_t stride;
- // The format of the buffer. One of WINDOW_FORMAT_*
+ // The format of the buffer. One of AHARDWAREBUFFER_FORMAT_*
int32_t format;
// The actual bits.
@@ -127,7 +127,7 @@
int32_t ANativeWindow_getHeight(ANativeWindow* window);
/**
- * Return the current pixel format of the window surface. Returns a
+ * Return the current pixel format (AHARDWAREBUFFER_FORMAT_*) of the window surface. Returns a
* negative value on error.
*/
int32_t ANativeWindow_getFormat(ANativeWindow* window);
@@ -135,6 +135,8 @@
/**
* Change the format and size of the window buffers.
*
+ * format: one of AHARDWAREBUFFER_FORMAT_ constants
+ *
* The width and height control the number of pixels in the buffers, not the
* dimensions of the window on screen. If these are different than the
* window's physical size, then it buffer will be scaled to match that size
diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h
index fdb37c2..63d1ad1 100644
--- a/libs/nativewindow/include/system/window.h
+++ b/libs/nativewindow/include/system/window.h
@@ -56,31 +56,7 @@
/*****************************************************************************/
-#ifdef __cplusplus
-#define ANDROID_NATIVE_UNSIGNED_CAST(x) static_cast<unsigned int>(x)
-#else
-#define ANDROID_NATIVE_UNSIGNED_CAST(x) ((unsigned int)(x))
-#endif
-
-#define ANDROID_NATIVE_MAKE_CONSTANT(a,b,c,d) \
- ((ANDROID_NATIVE_UNSIGNED_CAST(a) << 24) | \
- (ANDROID_NATIVE_UNSIGNED_CAST(b) << 16) | \
- (ANDROID_NATIVE_UNSIGNED_CAST(c) << 8) | \
- (ANDROID_NATIVE_UNSIGNED_CAST(d)))
-
-#define ANDROID_NATIVE_WINDOW_MAGIC \
- ANDROID_NATIVE_MAKE_CONSTANT('_','w','n','d')
-
-#define ANDROID_NATIVE_BUFFER_MAGIC \
- ANDROID_NATIVE_MAKE_CONSTANT('_','b','f','r')
-
-// ---------------------------------------------------------------------------
-
-// This #define may be used to conditionally compile device-specific code to
-// support either the prior ANativeWindow interface, which did not pass libsync
-// fences around, or the new interface that does. This #define is only present
-// when the ANativeWindow interface does include libsync support.
-#define ANDROID_NATIVE_WINDOW_HAS_SYNC 1
+#define ANDROID_NATIVE_WINDOW_MAGIC ANDROID_NATIVE_MAKE_CONSTANT('_','w','n','d')
// ---------------------------------------------------------------------------
@@ -98,56 +74,6 @@
// ---------------------------------------------------------------------------
-typedef struct android_native_base_t
-{
- /* a magic value defined by the actual EGL native type */
- int magic;
-
- /* the sizeof() of the actual EGL native type */
- int version;
-
- void* reserved[4];
-
- /* reference-counting interface */
- void (*incRef)(struct android_native_base_t* base);
- void (*decRef)(struct android_native_base_t* base);
-} android_native_base_t;
-
-typedef struct ANativeWindowBuffer
-{
-#ifdef __cplusplus
- ANativeWindowBuffer() {
- common.magic = ANDROID_NATIVE_BUFFER_MAGIC;
- common.version = sizeof(ANativeWindowBuffer);
- memset(common.reserved, 0, sizeof(common.reserved));
- }
-
- // Implement the methods that sp<ANativeWindowBuffer> expects so that it
- // can be used to automatically refcount ANativeWindowBuffer's.
- void incStrong(const void* /*id*/) const {
- common.incRef(const_cast<android_native_base_t*>(&common));
- }
- void decStrong(const void* /*id*/) const {
- common.decRef(const_cast<android_native_base_t*>(&common));
- }
-#endif
-
- struct android_native_base_t common;
-
- int width;
- int height;
- int stride;
- int format;
- int usage;
- uintptr_t layerCount;
-
- void* reserved[1];
-
- buffer_handle_t handle;
-
- void* reserved_proc[8];
-} ANativeWindowBuffer_t;
-
// Old typedef for backwards compatibility.
typedef ANativeWindowBuffer_t android_native_buffer_t;
@@ -159,25 +85,8 @@
NATIVE_WINDOW_HEIGHT = 1,
NATIVE_WINDOW_FORMAT = 2,
- /* The minimum number of buffers that must remain un-dequeued after a buffer
- * has been queued. This value applies only if set_buffer_count was used to
- * override the number of buffers and if a buffer has since been queued.
- * Users of the set_buffer_count ANativeWindow method should query this
- * value before calling set_buffer_count. If it is necessary to have N
- * buffers simultaneously dequeued as part of the steady-state operation,
- * and this query returns M then N+M buffers should be requested via
- * native_window_set_buffer_count.
- *
- * Note that this value does NOT apply until a single buffer has been
- * queued. In particular this means that it is possible to:
- *
- * 1. Query M = min undequeued buffers
- * 2. Set the buffer count to N + M
- * 3. Dequeue all N + M buffers
- * 4. Cancel M buffers
- * 5. Queue, dequeue, queue, dequeue, ad infinitum
- */
- NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS = 3,
+ /* see ANativeWindowQuery in vndk/window.h */
+ NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS = ANATIVEWINDOW_QUERY_MIN_UNDEQUEUED_BUFFERS,
/* Check whether queueBuffer operations on the ANativeWindow send the buffer
* to the window compositor. The query sets the returned 'value' argument
@@ -209,57 +118,11 @@
* NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS call and match the native window
* size unless overridden by NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS.
*/
- NATIVE_WINDOW_DEFAULT_WIDTH = 6,
- NATIVE_WINDOW_DEFAULT_HEIGHT = 7,
+ NATIVE_WINDOW_DEFAULT_WIDTH = ANATIVEWINDOW_QUERY_DEFAULT_WIDTH,
+ NATIVE_WINDOW_DEFAULT_HEIGHT = ANATIVEWINDOW_QUERY_DEFAULT_HEIGHT,
- /*
- * transformation that will most-likely be applied to buffers. This is only
- * a hint, the actual transformation applied might be different.
- *
- * INTENDED USE:
- *
- * The transform hint can be used by a producer, for instance the GLES
- * driver, to pre-rotate the rendering such that the final transformation
- * in the composer is identity. This can be very useful when used in
- * conjunction with the h/w composer HAL, in situations where it
- * cannot handle arbitrary rotations.
- *
- * 1. Before dequeuing a buffer, the GL driver (or any other ANW client)
- * queries the ANW for NATIVE_WINDOW_TRANSFORM_HINT.
- *
- * 2. The GL driver overrides the width and height of the ANW to
- * account for NATIVE_WINDOW_TRANSFORM_HINT. This is done by querying
- * NATIVE_WINDOW_DEFAULT_{WIDTH | HEIGHT}, swapping the dimensions
- * according to NATIVE_WINDOW_TRANSFORM_HINT and calling
- * native_window_set_buffers_dimensions().
- *
- * 3. The GL driver dequeues a buffer of the new pre-rotated size.
- *
- * 4. The GL driver renders to the buffer such that the image is
- * already transformed, that is applying NATIVE_WINDOW_TRANSFORM_HINT
- * to the rendering.
- *
- * 5. The GL driver calls native_window_set_transform to apply
- * inverse transformation to the buffer it just rendered.
- * In order to do this, the GL driver needs
- * to calculate the inverse of NATIVE_WINDOW_TRANSFORM_HINT, this is
- * done easily:
- *
- * int hintTransform, inverseTransform;
- * query(..., NATIVE_WINDOW_TRANSFORM_HINT, &hintTransform);
- * inverseTransform = hintTransform;
- * if (hintTransform & HAL_TRANSFORM_ROT_90)
- * inverseTransform ^= HAL_TRANSFORM_ROT_180;
- *
- *
- * 6. The GL driver queues the pre-transformed buffer.
- *
- * 7. The composer combines the buffer transform with the display
- * transform. If the buffer transform happens to cancel out the
- * display transform then no rotation is needed.
- *
- */
- NATIVE_WINDOW_TRANSFORM_HINT = 8,
+ /* see ANativeWindowQuery in vndk/window.h */
+ NATIVE_WINDOW_TRANSFORM_HINT = ANATIVEWINDOW_QUERY_TRANSFORM_HINT,
/*
* Boolean that indicates whether the consumer is running more than
@@ -298,14 +161,8 @@
*/
NATIVE_WINDOW_DEFAULT_DATASPACE = 12,
- /*
- * Returns the age of the contents of the most recently dequeued buffer as
- * the number of frames that have elapsed since it was last queued. For
- * example, if the window is double-buffered, the age of any given buffer in
- * steady state will be 2. If the dequeued buffer has never been queued, its
- * age will be 0.
- */
- NATIVE_WINDOW_BUFFER_AGE = 13,
+ /* see ANativeWindowQuery in vndk/window.h */
+ NATIVE_WINDOW_BUFFER_AGE = ANATIVEWINDOW_QUERY_BUFFER_AGE,
/*
* Returns the duration of the last dequeueBuffer call in microseconds
diff --git a/libs/nativewindow/include/vndk/window.h b/libs/nativewindow/include/vndk/window.h
index a4ed8fc..89585f3 100644
--- a/libs/nativewindow/include/vndk/window.h
+++ b/libs/nativewindow/include/vndk/window.h
@@ -17,18 +17,390 @@
#ifndef ANDROID_VNDK_NATIVEWINDOW_ANATIVEWINDOW_H
#define ANDROID_VNDK_NATIVEWINDOW_ANATIVEWINDOW_H
+#include <stdint.h>
+#include <stdbool.h>
#include <sys/cdefs.h>
+#include <system/graphics-base.h>
+#include <cutils/native_handle.h>
// vndk is a superset of the NDK
#include <android/native_window.h>
__BEGIN_DECLS
-// opaque native window structure
-struct ANativeWindow;
-typedef struct ANativeWindow ANativeWindow_t;
+/*****************************************************************************/
+
+#ifdef __cplusplus
+#define ANDROID_NATIVE_UNSIGNED_CAST(x) static_cast<unsigned int>(x)
+#else
+#define ANDROID_NATIVE_UNSIGNED_CAST(x) ((unsigned int)(x))
+#endif
+
+#define ANDROID_NATIVE_MAKE_CONSTANT(a,b,c,d) \
+ ((ANDROID_NATIVE_UNSIGNED_CAST(a) << 24) | \
+ (ANDROID_NATIVE_UNSIGNED_CAST(b) << 16) | \
+ (ANDROID_NATIVE_UNSIGNED_CAST(c) << 8) | \
+ (ANDROID_NATIVE_UNSIGNED_CAST(d)))
+
+#define ANDROID_NATIVE_BUFFER_MAGIC ANDROID_NATIVE_MAKE_CONSTANT('_','b','f','r')
+/*****************************************************************************/
+
+typedef struct android_native_base_t
+{
+ /* a magic value defined by the actual EGL native type */
+ int magic;
+
+ /* the sizeof() of the actual EGL native type */
+ int version;
+
+ void* reserved[4];
+
+ /* reference-counting interface */
+ void (*incRef)(struct android_native_base_t* base);
+ void (*decRef)(struct android_native_base_t* base);
+} android_native_base_t;
+
+typedef struct ANativeWindowBuffer
+{
+#ifdef __cplusplus
+ ANativeWindowBuffer() {
+ common.magic = ANDROID_NATIVE_BUFFER_MAGIC;
+ common.version = sizeof(ANativeWindowBuffer);
+ memset(common.reserved, 0, sizeof(common.reserved));
+ }
+
+ // Implement the methods that sp<ANativeWindowBuffer> expects so that it
+ // can be used to automatically refcount ANativeWindowBuffer's.
+ void incStrong(const void* /*id*/) const {
+ common.incRef(const_cast<android_native_base_t*>(&common));
+ }
+ void decStrong(const void* /*id*/) const {
+ common.decRef(const_cast<android_native_base_t*>(&common));
+ }
+#endif
+
+ struct android_native_base_t common;
+
+ int width;
+ int height;
+ int stride;
+ int format;
+ int usage;
+ uintptr_t layerCount;
+
+ void* reserved[1];
+
+ const native_handle_t* handle;
+
+ void* reserved_proc[8];
+} ANativeWindowBuffer_t;
+
+typedef struct ANativeWindowBuffer ANativeWindowBuffer;
+
+/*****************************************************************************/
+
+
+/*
+ * Stores a value into one of the 4 available slots
+ * Retrieve the value with ANativeWindow_OemStorageGet()
+ *
+ * slot: 0 to 3
+ *
+ * Returns 0 on success or -errno on error.
+ */
+int ANativeWindow_OemStorageSet(ANativeWindow* window, uint32_t slot, intptr_t value);
+
+
+/*
+ * Retrieves a value from one of the 4 available slots
+ * By default the returned value is 0 if it wasn't set by ANativeWindow_OemStorageSet()
+ *
+ * slot: 0 to 3
+ *
+ * Returns 0 on success or -errno on error.
+ */
+int ANativeWindow_OemStorageGet(ANativeWindow* window, uint32_t slot, intptr_t* value);
+
+
+/*
+ * Set the swap interval for this surface.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+int ANativeWindow_setSwapInterval(ANativeWindow* window, int interval);
+
+
+/*
+ * queries that can be used with ANativeWindow_query() and ANativeWindow_queryf()
+ */
+enum ANativeWindowQuery {
+ /* The minimum number of buffers that must remain un-dequeued after a buffer
+ * has been queued. This value applies only if set_buffer_count was used to
+ * override the number of buffers and if a buffer has since been queued.
+ * Users of the set_buffer_count ANativeWindow method should query this
+ * value before calling set_buffer_count. If it is necessary to have N
+ * buffers simultaneously dequeued as part of the steady-state operation,
+ * and this query returns M then N+M buffers should be requested via
+ * native_window_set_buffer_count.
+ *
+ * Note that this value does NOT apply until a single buffer has been
+ * queued. In particular this means that it is possible to:
+ *
+ * 1. Query M = min undequeued buffers
+ * 2. Set the buffer count to N + M
+ * 3. Dequeue all N + M buffers
+ * 4. Cancel M buffers
+ * 5. Queue, dequeue, queue, dequeue, ad infinitum
+ */
+ ANATIVEWINDOW_QUERY_MIN_UNDEQUEUED_BUFFERS = 3,
+
+ /*
+ * Default width of ANativeWindow buffers, these are the
+ * dimensions of the window buffers irrespective of the
+ * ANativeWindow_setBuffersDimensions() call and match the native window
+ * size.
+ */
+ ANATIVEWINDOW_QUERY_DEFAULT_WIDTH = 6,
+ ANATIVEWINDOW_QUERY_DEFAULT_HEIGHT = 7,
+
+ /*
+ * transformation that will most-likely be applied to buffers. This is only
+ * a hint, the actual transformation applied might be different.
+ *
+ * INTENDED USE:
+ *
+ * The transform hint can be used by a producer, for instance the GLES
+ * driver, to pre-rotate the rendering such that the final transformation
+ * in the composer is identity. This can be very useful when used in
+ * conjunction with the h/w composer HAL, in situations where it
+ * cannot handle arbitrary rotations.
+ *
+ * 1. Before dequeuing a buffer, the GL driver (or any other ANW client)
+ * queries the ANW for NATIVE_WINDOW_TRANSFORM_HINT.
+ *
+ * 2. The GL driver overrides the width and height of the ANW to
+ * account for NATIVE_WINDOW_TRANSFORM_HINT. This is done by querying
+ * NATIVE_WINDOW_DEFAULT_{WIDTH | HEIGHT}, swapping the dimensions
+ * according to NATIVE_WINDOW_TRANSFORM_HINT and calling
+ * native_window_set_buffers_dimensions().
+ *
+ * 3. The GL driver dequeues a buffer of the new pre-rotated size.
+ *
+ * 4. The GL driver renders to the buffer such that the image is
+ * already transformed, that is applying NATIVE_WINDOW_TRANSFORM_HINT
+ * to the rendering.
+ *
+ * 5. The GL driver calls native_window_set_transform to apply
+ * inverse transformation to the buffer it just rendered.
+ * In order to do this, the GL driver needs
+ * to calculate the inverse of NATIVE_WINDOW_TRANSFORM_HINT, this is
+ * done easily:
+ *
+ * int hintTransform, inverseTransform;
+ * query(..., NATIVE_WINDOW_TRANSFORM_HINT, &hintTransform);
+ * inverseTransform = hintTransform;
+ * if (hintTransform & HAL_TRANSFORM_ROT_90)
+ * inverseTransform ^= HAL_TRANSFORM_ROT_180;
+ *
+ *
+ * 6. The GL driver queues the pre-transformed buffer.
+ *
+ * 7. The composer combines the buffer transform with the display
+ * transform. If the buffer transform happens to cancel out the
+ * display transform then no rotation is needed.
+ *
+ */
+ ANATIVEWINDOW_QUERY_TRANSFORM_HINT = 8,
+
+ /*
+ * Returns the age of the contents of the most recently dequeued buffer as
+ * the number of frames that have elapsed since it was last queued. For
+ * example, if the window is double-buffered, the age of any given buffer in
+ * steady state will be 2. If the dequeued buffer has never been queued, its
+ * age will be 0.
+ */
+ ANATIVEWINDOW_QUERY_BUFFER_AGE = 13,
+
+ /* min swap interval supported by this compositor */
+ ANATIVEWINDOW_QUERY_MIN_SWAP_INTERVAL = 0x10000,
+
+ /* max swap interval supported by this compositor */
+ ANATIVEWINDOW_QUERY_MAX_SWAP_INTERVAL = 0x10001,
+
+ /* horizontal resolution in DPI. value is float, use queryf() */
+ ANATIVEWINDOW_QUERY_XDPI = 0x10002,
+
+ /* vertical resolution in DPI. value is float, use queryf() */
+ ANATIVEWINDOW_QUERY_YDPI = 0x10003,
+};
+
+/*
+ * hook used to retrieve information about the native window.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+int ANativeWindow_query(const ANativeWindow* window, ANativeWindowQuery query, int* value);
+int ANativeWindow_queryf(const ANativeWindow* window, ANativeWindowQuery query, float* value);
+
+
+/*
+ * Hook called by EGL to acquire a buffer. This call may block if no
+ * buffers are available.
+ *
+ * The window holds a reference to the buffer between dequeueBuffer and
+ * either queueBuffer or cancelBuffer, so clients only need their own
+ * reference if they might use the buffer after queueing or canceling it.
+ * Holding a reference to a buffer after queueing or canceling it is only
+ * allowed if a specific buffer count has been set.
+ *
+ * The libsync fence file descriptor returned in the int pointed to by the
+ * fenceFd argument will refer to the fence that must signal before the
+ * dequeued buffer may be written to. A value of -1 indicates that the
+ * caller may access the buffer immediately without waiting on a fence. If
+ * a valid file descriptor is returned (i.e. any value except -1) then the
+ * caller is responsible for closing the file descriptor.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+int ANativeWindow_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer, int* fenceFd);
+
+
+/*
+ * Hook called by EGL when modifications to the render buffer are done.
+ * This unlocks and post the buffer.
+ *
+ * The window holds a reference to the buffer between dequeueBuffer and
+ * either queueBuffer or cancelBuffer, so clients only need their own
+ * reference if they might use the buffer after queueing or canceling it.
+ * Holding a reference to a buffer after queueing or canceling it is only
+ * allowed if a specific buffer count has been set.
+ *
+ * The fenceFd argument specifies a libsync fence file descriptor for a
+ * fence that must signal before the buffer can be accessed. If the buffer
+ * can be accessed immediately then a value of -1 should be used. The
+ * caller must not use the file descriptor after it is passed to
+ * queueBuffer, and the ANativeWindow implementation is responsible for
+ * closing it.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+int ANativeWindow_queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd);
+
+
+/*
+ * Hook used to cancel a buffer that has been dequeued.
+ * No synchronization is performed between dequeue() and cancel(), so
+ * either external synchronization is needed, or these functions must be
+ * called from the same thread.
+ *
+ * The window holds a reference to the buffer between dequeueBuffer and
+ * either queueBuffer or cancelBuffer, so clients only need their own
+ * reference if they might use the buffer after queueing or canceling it.
+ * Holding a reference to a buffer after queueing or canceling it is only
+ * allowed if a specific buffer count has been set.
+ *
+ * The fenceFd argument specifies a libsync fence file decsriptor for a
+ * fence that must signal before the buffer can be accessed. If the buffer
+ * can be accessed immediately then a value of -1 should be used.
+ *
+ * Note that if the client has not waited on the fence that was returned
+ * from dequeueBuffer, that same fence should be passed to cancelBuffer to
+ * ensure that future uses of the buffer are preceded by a wait on that
+ * fence. The caller must not use the file descriptor after it is passed
+ * to cancelBuffer, and the ANativeWindow implementation is responsible for
+ * closing it.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+int ANativeWindow_cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd);
+
+/*
+ * Sets the intended usage flags for the next buffers.
+ *
+ * usage: one of AHARDWAREBUFFER_USAGE0_* constant
+ * privateUsage: one of AHARDWAREBUFFER_USAGE1_*_PRIVATE_* constant
+ *
+ * By default (if this function is never called), a usage of
+ * AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT
+ * is assumed.
+ *
+ * Calling this function will usually cause following buffers to be
+ * reallocated.
+ */
+int ANativeWindow_setUsage(ANativeWindow* window, uint64_t usage0, uint64_t usage1);
+
+
+/*
+ * Sets the number of buffers associated with this native window.
+ */
+int ANativeWindow_setBufferCount(ANativeWindow* window, size_t bufferCount);
+
+
+/*
+ * All buffers dequeued after this call will have the dimensions specified.
+ * In particular, all buffers will have a fixed-size, independent from the
+ * native-window size. They will be scaled according to the scaling mode
+ * (see native_window_set_scaling_mode) upon window composition.
+ *
+ * If w and h are 0, the normal behavior is restored. That is, dequeued buffers
+ * following this call will be sized to match the window's size.
+ *
+ * Calling this function will reset the window crop to a NULL value, which
+ * disables cropping of the buffers.
+ */
+int ANativeWindow_setBuffersDimensions(ANativeWindow* window, uint32_t w, uint32_t h);
+
+
+/*
+ * All buffers dequeued after this call will have the format specified.
+ * format: one of AHARDWAREBUFFER_FORMAT_* constant
+ *
+ * If the specified format is 0, the default buffer format will be used.
+ */
+int ANativeWindow_setBuffersFormat(ANativeWindow* window, int format);
+
+
+/*
+ * All buffers queued after this call will be associated with the timestamp in nanosecond
+ * parameter specified. If the timestamp is set to NATIVE_WINDOW_TIMESTAMP_AUTO
+ * (the default), timestamps will be generated automatically when queueBuffer is
+ * called. The timestamp is measured in nanoseconds, and is normally monotonically
+ * increasing. The timestamp should be unaffected by time-of-day adjustments,
+ * and for a camera should be strictly monotonic but for a media player may be
+ * reset when the position is set.
+ */
+int ANativeWindow_setBuffersTimestamp(ANativeWindow* window, int64_t timestamp);
+
+
+/*
+ * All buffers queued after this call will be associated with the dataSpace
+ * parameter specified.
+ *
+ * dataSpace specifies additional information about the buffer that's dependent
+ * on the buffer format and the endpoints. For example, it can be used to convey
+ * the color space of the image data in the buffer, or it can be used to
+ * indicate that the buffers contain depth measurement data instead of color
+ * images. The default dataSpace is 0, HAL_DATASPACE_UNKNOWN, unless it has been
+ * overridden by the consumer.
+ */
+int ANativeWindow_setBufferDataSpace(ANativeWindow* window, android_dataspace_t dataSpace);
+
+
+/*
+ * Enable/disable shared buffer mode
+ */
+int ANativeWindow_setSharedBufferMode(ANativeWindow* window, bool sharedBufferMode);
+
+
+/*
+ * Enable/disable auto refresh when in shared buffer mode
+ */
+int ANativeWindow_setAutoRefresh(ANativeWindow* window, bool autoRefresh);
+
+
+/*****************************************************************************/
__END_DECLS