split libandroid.so
- ANativeWindow (native_window.h) and
AHardwareBuffer (hardware_buffer.h) now live
in libnativewindow.so, which is a vodka library.
- libandroid.so still provide those symbols
via a static library version (libnativewindow.a)
- removed libbinder dependency as well
Test: compiled & booted
Bug: 35164655
Change-Id: Ib4bc8e8fc9ec1891bcbee63c28fd0131d82edf29
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index ddf1072..8f9c38a 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -107,6 +107,7 @@
"libGLESv2",
"libui",
"libutils",
+ "libnativewindow",
"liblog",
],
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index 092d597..5944110 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -15,7 +15,6 @@
"IGraphicBufferProducer_test.cpp",
"MultiTextureConsumer_test.cpp",
"Sensor_test.cpp",
- "SRGB_test.cpp",
"StreamSplitter_test.cpp",
"SurfaceTextureClient_test.cpp",
"SurfaceTextureFBO_test.cpp",
@@ -37,5 +36,6 @@
"libgui",
"libui",
"libutils",
+ "libnativewindow"
],
}
diff --git a/libs/gui/tests/SRGB_test.cpp b/libs/gui/tests/SRGB_test.cpp
deleted file mode 100644
index c2640cd..0000000
--- a/libs/gui/tests/SRGB_test.cpp
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * Copyright 2013 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.
- */
-
-#define LOG_TAG "SRGB_test"
-//#define LOG_NDEBUG 0
-
-// Ignore for this file because it flags every instance of
-// ASSERT_EQ(GL_NO_ERROR, glGetError());
-#pragma clang diagnostic ignored "-Wsign-compare"
-
-#include "GLTest.h"
-
-#include <math.h>
-
-#include <gui/CpuConsumer.h>
-#include <gui/Surface.h>
-#include <gui/SurfaceComposerClient.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES3/gl3.h>
-
-#include <android/native_window.h>
-
-#include <gtest/gtest.h>
-
-namespace android {
-
-class SRGBTest : public ::testing::Test {
-protected:
- // Class constants
- enum {
- DISPLAY_WIDTH = 512,
- DISPLAY_HEIGHT = 512,
- PIXEL_SIZE = 4, // bytes or components
- DISPLAY_SIZE = DISPLAY_WIDTH * DISPLAY_HEIGHT * PIXEL_SIZE,
- ALPHA_VALUE = 223, // should be in [0, 255]
- TOLERANCE = 1,
- };
- static const char SHOW_DEBUG_STRING[];
-
- SRGBTest() :
- mInputSurface(), mCpuConsumer(), mLockedBuffer(),
- mEglDisplay(EGL_NO_DISPLAY), mEglConfig(),
- mEglContext(EGL_NO_CONTEXT), mEglSurface(EGL_NO_SURFACE),
- mComposerClient(), mSurfaceControl(), mOutputSurface() {
- }
-
- virtual ~SRGBTest() {
- if (mEglDisplay != EGL_NO_DISPLAY) {
- if (mEglSurface != EGL_NO_SURFACE) {
- eglDestroySurface(mEglDisplay, mEglSurface);
- }
- if (mEglContext != EGL_NO_CONTEXT) {
- eglDestroyContext(mEglDisplay, mEglContext);
- }
- eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
- EGL_NO_CONTEXT);
- eglTerminate(mEglDisplay);
- }
- }
-
- virtual void SetUp() {
- sp<IGraphicBufferProducer> producer;
- sp<IGraphicBufferConsumer> consumer;
- BufferQueue::createBufferQueue(&producer, &consumer);
- ASSERT_EQ(NO_ERROR, consumer->setDefaultBufferSize(
- DISPLAY_WIDTH, DISPLAY_HEIGHT));
- mCpuConsumer = new CpuConsumer(consumer, 1);
- String8 name("CpuConsumer_for_SRGBTest");
- mCpuConsumer->setName(name);
- mInputSurface = new Surface(producer);
-
- ASSERT_NO_FATAL_FAILURE(createEGLSurface(mInputSurface.get()));
- ASSERT_NO_FATAL_FAILURE(createDebugSurface());
- }
-
- virtual void TearDown() {
- ASSERT_NO_FATAL_FAILURE(copyToDebugSurface());
- ASSERT_TRUE(mLockedBuffer.data != NULL);
- ASSERT_EQ(NO_ERROR, mCpuConsumer->unlockBuffer(mLockedBuffer));
- }
-
- static float linearToSRGB(float l) {
- if (l <= 0.0031308f) {
- return l * 12.92f;
- } else {
- return 1.055f * pow(l, (1 / 2.4f)) - 0.055f;
- }
- }
-
- static float srgbToLinear(float s) {
- if (s <= 0.04045) {
- return s / 12.92f;
- } else {
- return pow(((s + 0.055f) / 1.055f), 2.4f);
- }
- }
-
- static uint8_t srgbToLinear(uint8_t u) {
- float f = u / 255.0f;
- return static_cast<uint8_t>(srgbToLinear(f) * 255.0f + 0.5f);
- }
-
- void fillTexture(bool writeAsSRGB) {
- uint8_t* textureData = new uint8_t[DISPLAY_SIZE];
-
- for (int y = 0; y < DISPLAY_HEIGHT; ++y) {
- for (int x = 0; x < DISPLAY_WIDTH; ++x) {
- float realValue = static_cast<float>(x) / (DISPLAY_WIDTH - 1);
- realValue *= ALPHA_VALUE / 255.0f; // Premultiply by alpha
- if (writeAsSRGB) {
- realValue = linearToSRGB(realValue);
- }
-
- int offset = (y * DISPLAY_WIDTH + x) * PIXEL_SIZE;
- for (int c = 0; c < 3; ++c) {
- uint8_t intValue = static_cast<uint8_t>(
- realValue * 255.0f + 0.5f);
- textureData[offset + c] = intValue;
- }
- textureData[offset + 3] = ALPHA_VALUE;
- }
- }
-
- glTexImage2D(GL_TEXTURE_2D, 0, writeAsSRGB ? GL_SRGB8_ALPHA8 : GL_RGBA8,
- DISPLAY_WIDTH, DISPLAY_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE,
- textureData);
- ASSERT_EQ(GL_NO_ERROR, glGetError());
-
- delete[] textureData;
- }
-
- void initShaders() {
- static const char vertexSource[] =
- "attribute vec4 vPosition;\n"
- "varying vec2 texCoords;\n"
- "void main() {\n"
- " texCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n"
- " gl_Position = vPosition;\n"
- "}\n";
-
- static const char fragmentSource[] =
- "precision mediump float;\n"
- "uniform sampler2D texSampler;\n"
- "varying vec2 texCoords;\n"
- "void main() {\n"
- " gl_FragColor = texture2D(texSampler, texCoords);\n"
- "}\n";
-
- GLuint program;
- {
- SCOPED_TRACE("Creating shader program");
- ASSERT_NO_FATAL_FAILURE(GLTest::createProgram(
- vertexSource, fragmentSource, &program));
- }
-
- GLint positionHandle = glGetAttribLocation(program, "vPosition");
- ASSERT_EQ(GL_NO_ERROR, glGetError());
- ASSERT_NE(-1, positionHandle);
-
- GLint samplerHandle = glGetUniformLocation(program, "texSampler");
- ASSERT_EQ(GL_NO_ERROR, glGetError());
- ASSERT_NE(-1, samplerHandle);
-
- static const GLfloat vertices[] = {
- -1.0f, 1.0f,
- -1.0f, -1.0f,
- 1.0f, -1.0f,
- 1.0f, 1.0f,
- };
-
- glVertexAttribPointer(positionHandle, 2, GL_FLOAT, GL_FALSE, 0, vertices);
- ASSERT_EQ(GL_NO_ERROR, glGetError());
- glEnableVertexAttribArray(positionHandle);
- ASSERT_EQ(GL_NO_ERROR, glGetError());
-
- glUseProgram(program);
- ASSERT_EQ(GL_NO_ERROR, glGetError());
- glUniform1i(samplerHandle, 0);
- ASSERT_EQ(GL_NO_ERROR, glGetError());
-
- GLuint textureHandle;
- glGenTextures(1, &textureHandle);
- ASSERT_EQ(GL_NO_ERROR, glGetError());
- glBindTexture(GL_TEXTURE_2D, textureHandle);
- ASSERT_EQ(GL_NO_ERROR, glGetError());
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- ASSERT_EQ(GL_NO_ERROR, glGetError());
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- ASSERT_EQ(GL_NO_ERROR, glGetError());
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- ASSERT_EQ(GL_NO_ERROR, glGetError());
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- ASSERT_EQ(GL_NO_ERROR, glGetError());
- }
-
- void drawTexture(bool asSRGB, GLint x, GLint y, GLsizei width,
- GLsizei height) {
- ASSERT_NO_FATAL_FAILURE(fillTexture(asSRGB));
- glViewport(x, y, width, height);
- ASSERT_EQ(GL_NO_ERROR, glGetError());
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- ASSERT_EQ(GL_NO_ERROR, glGetError());
- }
-
- void checkLockedBuffer(PixelFormat format, android_dataspace dataSpace) {
- ASSERT_EQ(mLockedBuffer.format, format);
- ASSERT_EQ(mLockedBuffer.width, DISPLAY_WIDTH);
- ASSERT_EQ(mLockedBuffer.height, DISPLAY_HEIGHT);
- ASSERT_EQ(mLockedBuffer.dataSpace, dataSpace);
- }
-
- static bool withinTolerance(int a, int b) {
- int diff = a - b;
- return diff >= 0 ? diff <= TOLERANCE : -diff <= TOLERANCE;
- }
-
- // Primary producer and consumer
- sp<Surface> mInputSurface;
- sp<CpuConsumer> mCpuConsumer;
- CpuConsumer::LockedBuffer mLockedBuffer;
-
- EGLDisplay mEglDisplay;
- EGLConfig mEglConfig;
- EGLContext mEglContext;
- EGLSurface mEglSurface;
-
- // Auxiliary display output
- sp<SurfaceComposerClient> mComposerClient;
- sp<SurfaceControl> mSurfaceControl;
- sp<Surface> mOutputSurface;
-
-private:
- void createEGLSurface(Surface* inputSurface) {
- mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
-
- EXPECT_TRUE(eglInitialize(mEglDisplay, NULL, NULL));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- static const EGLint configAttribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
- EGL_RED_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_BLUE_SIZE, 8,
- EGL_ALPHA_SIZE, 8,
- EGL_NONE };
-
- EGLint numConfigs = 0;
- EXPECT_TRUE(eglChooseConfig(mEglDisplay, configAttribs, &mEglConfig, 1,
- &numConfigs));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_GT(numConfigs, 0);
-
- static const EGLint contextAttribs[] = {
- EGL_CONTEXT_CLIENT_VERSION, 3,
- EGL_NONE } ;
-
- mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT,
- contextAttribs);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
-
- mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig,
- inputSurface, NULL);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
-
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
- mEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- }
-
- void createDebugSurface() {
- if (getenv(SHOW_DEBUG_STRING) == NULL) return;
-
- mComposerClient = new SurfaceComposerClient;
- ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
-
- mSurfaceControl = mComposerClient->createSurface(
- String8("SRGBTest Surface"), DISPLAY_WIDTH, DISPLAY_HEIGHT,
- PIXEL_FORMAT_RGBA_8888);
-
- ASSERT_TRUE(mSurfaceControl != NULL);
- ASSERT_TRUE(mSurfaceControl->isValid());
-
- SurfaceComposerClient::openGlobalTransaction();
- ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
- ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
- SurfaceComposerClient::closeGlobalTransaction();
-
- ANativeWindow_Buffer outBuffer;
- ARect inOutDirtyBounds;
- mOutputSurface = mSurfaceControl->getSurface();
- mOutputSurface->lock(&outBuffer, &inOutDirtyBounds);
- uint8_t* bytePointer = reinterpret_cast<uint8_t*>(outBuffer.bits);
- for (int y = 0; y < outBuffer.height; ++y) {
- int rowOffset = y * outBuffer.stride; // pixels
- for (int x = 0; x < outBuffer.width; ++x) {
- int colOffset = (rowOffset + x) * PIXEL_SIZE; // bytes
- for (int c = 0; c < PIXEL_SIZE; ++c) {
- int offset = colOffset + c;
- bytePointer[offset] = ((c + 1) * 56) - 1;
- }
- }
- }
- mOutputSurface->unlockAndPost();
- }
-
- void copyToDebugSurface() {
- if (!mOutputSurface.get()) return;
-
- size_t bufferSize = mLockedBuffer.height * mLockedBuffer.stride *
- PIXEL_SIZE;
-
- ANativeWindow_Buffer outBuffer;
- ARect outBufferBounds;
- mOutputSurface->lock(&outBuffer, &outBufferBounds);
- ASSERT_EQ(mLockedBuffer.width, static_cast<uint32_t>(outBuffer.width));
- ASSERT_EQ(mLockedBuffer.height, static_cast<uint32_t>(outBuffer.height));
- ASSERT_EQ(mLockedBuffer.stride, static_cast<uint32_t>(outBuffer.stride));
-
- if (mLockedBuffer.format == outBuffer.format) {
- memcpy(outBuffer.bits, mLockedBuffer.data, bufferSize);
- } else {
- ASSERT_EQ(mLockedBuffer.format, PIXEL_FORMAT_RGBA_8888);
- ASSERT_EQ(mLockedBuffer.dataSpace, HAL_DATASPACE_SRGB);
- ASSERT_EQ(outBuffer.format, PIXEL_FORMAT_RGBA_8888);
- uint8_t* outPointer = reinterpret_cast<uint8_t*>(outBuffer.bits);
- for (int y = 0; y < outBuffer.height; ++y) {
- int rowOffset = y * outBuffer.stride; // pixels
- for (int x = 0; x < outBuffer.width; ++x) {
- int colOffset = (rowOffset + x) * PIXEL_SIZE; // bytes
-
- // RGB are converted
- for (int c = 0; c < (PIXEL_SIZE - 1); ++c) {
- outPointer[colOffset + c] = srgbToLinear(
- mLockedBuffer.data[colOffset + c]);
- }
-
- // Alpha isn't converted
- outPointer[colOffset + 3] =
- mLockedBuffer.data[colOffset + 3];
- }
- }
- }
- mOutputSurface->unlockAndPost();
-
- int sleepSeconds = atoi(getenv(SHOW_DEBUG_STRING));
- sleep(sleepSeconds);
- }
-};
-
-const char SRGBTest::SHOW_DEBUG_STRING[] = "DEBUG_OUTPUT_SECONDS";
-
-TEST_F(SRGBTest, GLRenderFromSRGBTexture) {
- ASSERT_NO_FATAL_FAILURE(initShaders());
-
- // The RGB texture is displayed in the top half
- ASSERT_NO_FATAL_FAILURE(drawTexture(false, 0, DISPLAY_HEIGHT / 2,
- DISPLAY_WIDTH, DISPLAY_HEIGHT / 2));
-
- // The SRGB texture is displayed in the bottom half
- ASSERT_NO_FATAL_FAILURE(drawTexture(true, 0, 0,
- DISPLAY_WIDTH, DISPLAY_HEIGHT / 2));
-
- eglSwapBuffers(mEglDisplay, mEglSurface);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- // Lock
- ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer));
- ASSERT_NO_FATAL_FAILURE(
- checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_UNKNOWN));
-
- // Compare a pixel in the middle of each texture
- int midSRGBOffset = (DISPLAY_HEIGHT / 4) * mLockedBuffer.stride *
- PIXEL_SIZE;
- int midRGBOffset = midSRGBOffset * 3;
- midRGBOffset += (DISPLAY_WIDTH / 2) * PIXEL_SIZE;
- midSRGBOffset += (DISPLAY_WIDTH / 2) * PIXEL_SIZE;
- for (int c = 0; c < PIXEL_SIZE; ++c) {
- int expectedValue = mLockedBuffer.data[midRGBOffset + c];
- int actualValue = mLockedBuffer.data[midSRGBOffset + c];
- ASSERT_PRED2(withinTolerance, expectedValue, actualValue);
- }
-
- // mLockedBuffer is unlocked in TearDown so we can copy data from it to
- // the debug surface if necessary
-}
-
-// XXX: Disabled since we don't currently expect this to work
-TEST_F(SRGBTest, DISABLED_RenderToSRGBSurface) {
- ASSERT_NO_FATAL_FAILURE(initShaders());
-
- // By default, the first buffer we write into will be RGB
-
- // Render an RGB texture across the whole surface
- ASSERT_NO_FATAL_FAILURE(drawTexture(false, 0, 0,
- DISPLAY_WIDTH, DISPLAY_HEIGHT));
- eglSwapBuffers(mEglDisplay, mEglSurface);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- // Lock
- ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer));
- ASSERT_NO_FATAL_FAILURE(
- checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_UNKNOWN));
-
- // Save the values of the middle pixel for later comparison against SRGB
- uint8_t values[PIXEL_SIZE] = {};
- int middleOffset = (DISPLAY_HEIGHT / 2) * mLockedBuffer.stride *
- PIXEL_SIZE;
- middleOffset += (DISPLAY_WIDTH / 2) * PIXEL_SIZE;
- for (int c = 0; c < PIXEL_SIZE; ++c) {
- values[c] = mLockedBuffer.data[middleOffset + c];
- }
-
- // Unlock
- ASSERT_EQ(NO_ERROR, mCpuConsumer->unlockBuffer(mLockedBuffer));
-
- // Switch to SRGB window surface
- static const int srgbAttribs[] = {
- EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR,
- EGL_NONE,
- };
-
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
- mEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- EXPECT_TRUE(eglDestroySurface(mEglDisplay, mEglSurface));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig,
- mInputSurface.get(), srgbAttribs);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
- ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
-
- EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
- mEglContext));
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- // Render the texture again
- ASSERT_NO_FATAL_FAILURE(drawTexture(false, 0, 0,
- DISPLAY_WIDTH, DISPLAY_HEIGHT));
- eglSwapBuffers(mEglDisplay, mEglSurface);
- ASSERT_EQ(EGL_SUCCESS, eglGetError());
-
- // Lock
- ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer));
-
- // Make sure we actually got the SRGB buffer on the consumer side
- ASSERT_NO_FATAL_FAILURE(
- checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_SRGB));
-
- // Verify that the stored value is the same, accounting for RGB/SRGB
- for (int c = 0; c < PIXEL_SIZE; ++c) {
- // The alpha value should be equivalent before linear->SRGB
- float rgbAsSRGB = (c == 3) ? values[c] / 255.0f :
- linearToSRGB(values[c] / 255.0f);
- int expectedValue = rgbAsSRGB * 255.0f + 0.5f;
- int actualValue = mLockedBuffer.data[middleOffset + c];
- ASSERT_PRED2(withinTolerance, expectedValue, actualValue);
- }
-
- // mLockedBuffer is unlocked in TearDown so we can copy data from it to
- // the debug surface if necessary
-}
-
-} // namespace android
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
new file mode 100644
index 0000000..b4b5303
--- /dev/null
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#define LOG_TAG "AHardwareBuffer"
+
+#include <android/hardware_buffer.h>
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <memory>
+
+#include <cutils/native_handle.h>
+#include <log/log.h>
+#include <utils/StrongPointer.h>
+#include <ui/GraphicBuffer.h>
+#include <system/graphics.h>
+#include <hardware/gralloc1.h>
+
+#include <private/android/AHardwareBufferHelpers.h>
+
+
+static constexpr int kDataBufferSize = 64 * sizeof(int); // 64 ints
+
+using namespace android;
+
+// ----------------------------------------------------------------------------
+// Public functions
+// ----------------------------------------------------------------------------
+
+int AHardwareBuffer_allocate(const AHardwareBuffer_Desc* desc, AHardwareBuffer** outBuffer) {
+ if (!outBuffer || !desc)
+ return BAD_VALUE;
+
+ int format = AHardwareBuffer_convertToPixelFormat(desc->format);
+ if (format == 0) {
+ ALOGE("Invalid pixel format %u", desc->format);
+ return BAD_VALUE;
+ }
+
+ if (desc->format == AHARDWAREBUFFER_FORMAT_BLOB && desc->height != 1) {
+ ALOGE("Height must be 1 when using the AHARDWAREBUFFER_FORMAT_BLOB format");
+ return BAD_VALUE;
+ }
+
+ uint64_t producerUsage = 0;
+ uint64_t consumerUsage = 0;
+ AHardwareBuffer_convertToGrallocUsageBits(desc->usage0, &producerUsage, &consumerUsage);
+
+ sp<GraphicBuffer> gbuffer(new GraphicBuffer(
+ desc->width, desc->height, format, desc->layers, producerUsage, consumerUsage,
+ std::string("AHardwareBuffer pid [") + std::to_string(getpid()) + "]"));
+
+ status_t err = gbuffer->initCheck();
+ if (err != 0 || gbuffer->handle == 0) {
+ if (err == NO_MEMORY) {
+ GraphicBuffer::dumpAllocationsToSystemLog();
+ }
+ ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%u, h=%u, lc=%u) failed (%s), handle=%p",
+ desc->width, desc->height, desc->layers, strerror(-err), gbuffer->handle);
+ return err;
+ }
+
+ *outBuffer = AHardwareBuffer_from_GraphicBuffer(gbuffer.get());
+
+ // Ensure the buffer doesn't get destroyed when the sp<> goes away.
+ AHardwareBuffer_acquire(*outBuffer);
+ return NO_ERROR;
+}
+
+void AHardwareBuffer_acquire(AHardwareBuffer* buffer) {
+ AHardwareBuffer_to_GraphicBuffer(buffer)->incStrong((void*)AHardwareBuffer_acquire);
+}
+
+void AHardwareBuffer_release(AHardwareBuffer* buffer) {
+ AHardwareBuffer_to_GraphicBuffer(buffer)->decStrong((void*)AHardwareBuffer_release);
+}
+
+void AHardwareBuffer_describe(const AHardwareBuffer* buffer,
+ AHardwareBuffer_Desc* outDesc) {
+ if (!buffer || !outDesc) return;
+
+ const GraphicBuffer* gbuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
+
+ outDesc->width = gbuffer->getWidth();
+ outDesc->height = gbuffer->getHeight();
+ outDesc->layers = gbuffer->getLayerCount();
+ outDesc->usage0 = AHardwareBuffer_convertFromGrallocUsageBits(
+ gbuffer->getUsage(), gbuffer->getUsage());
+ outDesc->usage1 = 0;
+ outDesc->format = AHardwareBuffer_convertFromPixelFormat(
+ static_cast<uint32_t>(gbuffer->getPixelFormat()));
+}
+
+int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage0,
+ int32_t fence, const ARect* rect, void** outVirtualAddress) {
+ if (!buffer) return BAD_VALUE;
+
+ if (usage0 & ~(AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN |
+ AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN)) {
+ ALOGE("Invalid usage flags passed to AHardwareBuffer_lock; only "
+ " AHARDWAREBUFFER_USAGE0_CPU_* flags are allowed");
+ return BAD_VALUE;
+ }
+
+ uint64_t producerUsage = 0;
+ uint64_t consumerUsage = 0;
+ AHardwareBuffer_convertToGrallocUsageBits(usage0, &producerUsage, &consumerUsage);
+ GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
+ Rect bounds;
+ if (!rect) {
+ bounds.set(Rect(gBuffer->getWidth(), gBuffer->getHeight()));
+ } else {
+ bounds.set(Rect(rect->left, rect->top, rect->right, rect->bottom));
+ }
+ return gBuffer->lockAsync(producerUsage, consumerUsage, bounds,
+ outVirtualAddress, fence);
+}
+
+int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence) {
+ if (!buffer) return BAD_VALUE;
+
+ GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
+ return gBuffer->unlockAsync(fence);
+}
+
+int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer,
+ int socketFd) {
+ if (!buffer) return BAD_VALUE;
+ const GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
+
+ size_t flattenedSize = gBuffer->getFlattenedSize();
+ size_t fdCount = gBuffer->getFdCount();
+
+ std::unique_ptr<uint8_t[]> data(new uint8_t[flattenedSize]);
+ std::unique_ptr<int[]> fds(new int[fdCount]);
+
+ // Make copies of needed items since flatten modifies them, and we don't
+ // want to send anything if there's an error during flatten.
+ size_t flattenedSizeCopy = flattenedSize;
+ size_t fdCountCopy = fdCount;
+ void* dataStart = data.get();
+ int* fdsStart = fds.get();
+ status_t err = gBuffer->flatten(dataStart, flattenedSizeCopy, fdsStart,
+ fdCountCopy);
+ if (err != NO_ERROR) {
+ return err;
+ }
+
+ struct iovec iov[1];
+ iov[0].iov_base = data.get();
+ iov[0].iov_len = flattenedSize;
+
+ char buf[CMSG_SPACE(kDataBufferSize)];
+ struct msghdr msg = {
+ .msg_control = buf,
+ .msg_controllen = sizeof(buf),
+ .msg_iov = &iov[0],
+ .msg_iovlen = 1,
+ };
+
+ struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fdCount);
+ int* fdData = reinterpret_cast<int*>(CMSG_DATA(cmsg));
+ memcpy(fdData, fds.get(), sizeof(int) * fdCount);
+ msg.msg_controllen = cmsg->cmsg_len;
+
+ int result = sendmsg(socketFd, &msg, 0);
+ if (result <= 0) {
+ ALOGE("Error writing AHardwareBuffer to socket: error %#x (%s)",
+ result, strerror(errno));
+ return result;
+ }
+ return NO_ERROR;
+}
+
+int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd,
+ AHardwareBuffer** outBuffer) {
+ if (!outBuffer) return BAD_VALUE;
+
+ char dataBuf[CMSG_SPACE(kDataBufferSize)];
+ char fdBuf[CMSG_SPACE(kDataBufferSize)];
+ struct iovec iov[1];
+ iov[0].iov_base = dataBuf;
+ iov[0].iov_len = sizeof(dataBuf);
+
+ struct msghdr msg = {
+ .msg_control = fdBuf,
+ .msg_controllen = sizeof(fdBuf),
+ .msg_iov = &iov[0],
+ .msg_iovlen = 1,
+ };
+
+ int result = recvmsg(socketFd, &msg, 0);
+ if (result <= 0) {
+ ALOGE("Error reading AHardwareBuffer from socket: error %#x (%s)",
+ result, strerror(errno));
+ return result;
+ }
+
+ if (msg.msg_iovlen != 1) {
+ ALOGE("Error reading AHardwareBuffer from socket: bad data length");
+ return INVALID_OPERATION;
+ }
+
+ if (msg.msg_controllen % sizeof(int) != 0) {
+ ALOGE("Error reading AHardwareBuffer from socket: bad fd length");
+ return INVALID_OPERATION;
+ }
+
+ size_t dataLen = msg.msg_iov[0].iov_len;
+ const void* data = static_cast<const void*>(msg.msg_iov[0].iov_base);
+ if (!data) {
+ ALOGE("Error reading AHardwareBuffer from socket: no buffer data");
+ return INVALID_OPERATION;
+ }
+
+ struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
+ if (!cmsg) {
+ ALOGE("Error reading AHardwareBuffer from socket: no fd header");
+ return INVALID_OPERATION;
+ }
+
+ size_t fdCount = msg.msg_controllen >> 2;
+ const int* fdData = reinterpret_cast<const int*>(CMSG_DATA(cmsg));
+ if (!fdData) {
+ ALOGE("Error reading AHardwareBuffer from socket: no fd data");
+ return INVALID_OPERATION;
+ }
+
+ GraphicBuffer* gBuffer = new GraphicBuffer();
+ status_t err = gBuffer->unflatten(data, dataLen, fdData, fdCount);
+ if (err != NO_ERROR) {
+ return err;
+ }
+ *outBuffer = AHardwareBuffer_from_GraphicBuffer(gBuffer);
+ // Ensure the buffer has a positive ref-count.
+ AHardwareBuffer_acquire(*outBuffer);
+
+ return NO_ERROR;
+}
+
+const struct native_handle* AHardwareBuffer_getNativeHandle(
+ const AHardwareBuffer* buffer) {
+ if (!buffer) return nullptr;
+ const GraphicBuffer* gbuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
+ return gbuffer->handle;
+}
+
+
+// ----------------------------------------------------------------------------
+// Helpers implementation
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+static inline bool containsBits(uint64_t mask, uint64_t bitsToCheck) {
+ return (mask & bitsToCheck) == bitsToCheck;
+}
+
+uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t format) {
+ switch (format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888: return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
+ case HAL_PIXEL_FORMAT_RGBX_8888: return AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
+ case HAL_PIXEL_FORMAT_RGB_565: return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
+ case HAL_PIXEL_FORMAT_RGB_888: return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
+ case HAL_PIXEL_FORMAT_RGBA_FP16: return AHARDWAREBUFFER_FORMAT_R16G16B16A16_SFLOAT;
+ case HAL_PIXEL_FORMAT_RGBA_1010102: return AHARDWAREBUFFER_FORMAT_A2R10G10B10_UNORM_PACK32;
+ case HAL_PIXEL_FORMAT_BLOB: return AHARDWAREBUFFER_FORMAT_BLOB;
+ default:ALOGE("Unknown pixel format %u", format);
+ return 0;
+ }
+}
+
+uint32_t AHardwareBuffer_convertToPixelFormat(uint32_t format) {
+ switch (format) {
+ case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM: return HAL_PIXEL_FORMAT_RGBA_8888;
+ case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM: return HAL_PIXEL_FORMAT_RGBX_8888;
+ case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM: return HAL_PIXEL_FORMAT_RGB_565;
+ case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM: return HAL_PIXEL_FORMAT_RGB_888;
+ case AHARDWAREBUFFER_FORMAT_R16G16B16A16_SFLOAT: return HAL_PIXEL_FORMAT_RGBA_FP16;
+ case AHARDWAREBUFFER_FORMAT_A2R10G10B10_UNORM_PACK32: return HAL_PIXEL_FORMAT_RGBA_1010102;
+ case AHARDWAREBUFFER_FORMAT_BLOB: return HAL_PIXEL_FORMAT_BLOB;
+ default:ALOGE("Unknown AHardwareBuffer format %u", format);
+ return 0;
+ }
+}
+
+void AHardwareBuffer_convertToGrallocUsageBits(uint64_t usage, uint64_t* outProducerUsage,
+ uint64_t* outConsumerUsage) {
+ *outProducerUsage = 0;
+ *outConsumerUsage = 0;
+ if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_READ))
+ *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ;
+ if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN))
+ *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN;
+ if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_WRITE))
+ *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
+ if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN))
+ *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN;
+ if (containsBits(usage, AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE))
+ *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
+ if (containsBits(usage, AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT))
+ *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
+ // Not sure what this should be.
+ //if (containsBits(usage0, AHARDWAREBUFFER_USAGE0_GPU_CUBEMAP)) bits |= 0;
+ if (containsBits(usage, AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER))
+ *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER;
+ if (containsBits(usage, AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE))
+ *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER;
+ if (containsBits(usage, AHARDWAREBUFFER_USAGE0_PROTECTED_CONTENT))
+ *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_PROTECTED;
+ if (containsBits(usage, AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA))
+ *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA;
+}
+
+uint64_t AHardwareBuffer_convertFromGrallocUsageBits(uint64_t producerUsage, uint64_t consumerUsage) {
+ uint64_t bits = 0;
+ if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_CPU_READ))
+ bits |= AHARDWAREBUFFER_USAGE0_CPU_READ;
+ if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN))
+ bits |= AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN;
+ if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_CPU_WRITE))
+ bits |= AHARDWAREBUFFER_USAGE0_CPU_WRITE;
+ if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN))
+ bits |= AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN;
+ if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE))
+ bits |= AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE;
+ if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))
+ bits |= AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT;
+ if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER))
+ bits |= AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER;
+ if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER))
+ bits |= AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE;
+ if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_PROTECTED))
+ bits |= AHARDWAREBUFFER_USAGE0_PROTECTED_CONTENT;
+ if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA))
+ bits |= AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA;
+
+ return bits;
+}
+
+const GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(const AHardwareBuffer* buffer) {
+ return reinterpret_cast<const GraphicBuffer*>(buffer);
+}
+
+GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(AHardwareBuffer* buffer) {
+ return reinterpret_cast<GraphicBuffer*>(buffer);
+}
+
+AHardwareBuffer* AHardwareBuffer_from_GraphicBuffer(GraphicBuffer* buffer) {
+ return reinterpret_cast<AHardwareBuffer*>(buffer);
+}
+
+} // namespace android
diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp
new file mode 100644
index 0000000..34c136a
--- /dev/null
+++ b/libs/nativewindow/ANativeWindow.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#define LOG_TAG "ANativeWindow"
+
+#include <android/native_window.h>
+#include <system/window.h>
+
+void ANativeWindow_acquire(ANativeWindow* window) {
+ window->incStrong((void*)ANativeWindow_acquire);
+}
+
+void ANativeWindow_release(ANativeWindow* window) {
+ window->decStrong((void*)ANativeWindow_release);
+}
+
+static int32_t getWindowProp(ANativeWindow* window, int what) {
+ int value;
+ int res = window->query(window, what, &value);
+ return res < 0 ? res : value;
+}
+
+int32_t ANativeWindow_getWidth(ANativeWindow* window) {
+ return getWindowProp(window, NATIVE_WINDOW_WIDTH);
+}
+
+int32_t ANativeWindow_getHeight(ANativeWindow* window) {
+ return getWindowProp(window, NATIVE_WINDOW_HEIGHT);
+}
+
+int32_t ANativeWindow_getFormat(ANativeWindow* window) {
+ return getWindowProp(window, NATIVE_WINDOW_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);
+ if (!err) {
+ int mode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
+ if (width && height) {
+ mode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
+ }
+ err = native_window_set_scaling_mode(window, mode);
+ }
+ }
+ return err;
+}
+
+int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer,
+ ARect* inOutDirtyBounds) {
+ return window->perform(window, NATIVE_WINDOW_LOCK, outBuffer, inOutDirtyBounds);
+}
+
+int32_t ANativeWindow_unlockAndPost(ANativeWindow* window) {
+ return window->perform(window, NATIVE_WINDOW_UNLOCK_AND_POST);
+}
diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp
new file mode 100644
index 0000000..4d1d8ac
--- /dev/null
+++ b/libs/nativewindow/Android.bp
@@ -0,0 +1,50 @@
+// Copyright (C) 2017 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.
+
+ndk_headers {
+ name: "libnativewdinwow_headers",
+ from: "include/android",
+ to: "android",
+ srcs: ["include/android/*.h"],
+ license: "NOTICE",
+}
+
+cc_library {
+ name: "libnativewindow",
+ export_include_dirs: ["include"],
+
+ clang: true,
+
+ srcs: [
+ "AHardwareBuffer.cpp",
+ "ANativeWindow.cpp",
+ ],
+
+ shared_libs: [
+ "libhardware",
+ "libcutils",
+ "liblog",
+ "libutils",
+ "libui",
+ ],
+
+ static_libs: [
+ "libarect",
+ ],
+
+ // headers we include in our public headers
+ export_static_lib_headers: [
+ "libarect",
+ ],
+}
diff --git a/libs/nativewindow/MODULE_LICENSE_APACHE2 b/libs/nativewindow/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/nativewindow/MODULE_LICENSE_APACHE2
diff --git a/libs/nativewindow/NOTICE b/libs/nativewindow/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/libs/nativewindow/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-2008, 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.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
new file mode 100644
index 0000000..9c08c7b
--- /dev/null
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2017 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.
+ */
+
+/**
+ * @file hardware_buffer.h
+ */
+
+#ifndef ANDROID_HARDWARE_BUFFER_H
+#define ANDROID_HARDWARE_BUFFER_H
+
+#include <inttypes.h>
+
+#include <sys/cdefs.h>
+
+#include <android/rect.h>
+
+__BEGIN_DECLS
+
+/**
+ * Buffer pixel formats.
+ */
+enum {
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_R8G8B8A8_UNORM
+ * OpenGL ES: GL_RGBA8
+ */
+ AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,
+
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_R8G8B8A8_UNORM
+ * OpenGL ES: GL_RGBA8
+ */
+ AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM = 2,
+
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_R8G8B8_UNORM
+ * OpenGL ES: GL_RGB8
+ */
+ AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM = 3,
+
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_R5G6B5_UNORM_PACK16
+ * OpenGL ES: GL_RGB565
+ */
+ AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM = 4,
+
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_R16G16B16A16_SFLOAT
+ * OpenGL ES: GL_RGBA16F
+ */
+ AHARDWAREBUFFER_FORMAT_R16G16B16A16_SFLOAT = 0x16,
+
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_A2R10G10B10_UNORM_PACK32
+ * OpenGL ES: GL_RGB10_A2
+ */
+ AHARDWAREBUFFER_FORMAT_A2R10G10B10_UNORM_PACK32 = 0x2b,
+
+ /**
+ * An opaque binary blob format that must have height 1, with width equal to
+ * the buffer size in bytes.
+ */
+ AHARDWAREBUFFER_FORMAT_BLOB = 0x21,
+};
+
+enum {
+ /* 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,
+ /* 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,
+ /* 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 */
+ AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT = 1ULL << 11,
+ /* The buffer will be read from and written to by the GPU */
+ AHARDWAREBUFFER_USAGE0_GPU_STORAGE_IMAGE =
+ AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE |
+ AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT,
+ /* The buffer will be used as a cubemap texture */
+ AHARDWAREBUFFER_USAGE0_GPU_CUBEMAP = 1ULL << 13,
+ /* The buffer will be used as a shader storage or uniform buffer object*/
+ AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER = 1ULL << 14,
+ /* The buffer must not be used outside of a protected hardware path */
+ AHARDWAREBUFFER_USAGE0_PROTECTED_CONTENT = 1ULL << 18,
+ /** The buffer will be used for sensor direct data */
+ AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA = 1ULL << 29,
+ /* The buffer will be read by a hardware video encoder */
+ AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE = 1ULL << 21,
+};
+
+typedef struct AHardwareBuffer_Desc {
+ uint32_t width;
+ uint32_t height;
+ uint32_t layers;
+ uint64_t usage0; // Combination of AHARDWAREBUFFER_USAGE0_*
+ uint64_t usage1; // Initialize to zero, reserved for future use
+ uint32_t format; // One of AHARDWAREBUFFER_FORMAT_*
+} AHardwareBuffer_Desc;
+
+typedef struct AHardwareBuffer AHardwareBuffer;
+
+/**
+ * Allocates a buffer that backs an AHardwareBuffer using the passed
+ * AHardwareBuffer_Desc.
+ *
+ * Returns NO_ERROR on success, or an error number of the allocation fails for
+ * any reason.
+ */
+int AHardwareBuffer_allocate(const AHardwareBuffer_Desc* desc,
+ AHardwareBuffer** outBuffer);
+/**
+ * Acquire a reference on the given AHardwareBuffer object. This prevents the
+ * object from being deleted until the last reference is removed.
+ */
+void AHardwareBuffer_acquire(AHardwareBuffer* buffer);
+
+/**
+ * Remove a reference that was previously acquired with
+ * AHardwareBuffer_acquire().
+ */
+void AHardwareBuffer_release(AHardwareBuffer* buffer);
+
+/**
+ * Return a description of the AHardwareBuffer in the passed
+ * AHardwareBuffer_Desc struct.
+ */
+void AHardwareBuffer_describe(const AHardwareBuffer* buffer,
+ AHardwareBuffer_Desc* outDesc);
+
+/*
+ * Lock the AHardwareBuffer for reading or writing, depending on the usage flags
+ * passed. This call may block if the hardware needs to finish rendering or if
+ * CPU caches need to be synchronized, or possibly for other implementation-
+ * specific reasons. If fence is not negative, then it specifies a fence file
+ * descriptor that will be signaled when the buffer is locked, otherwise the
+ * caller will block until the buffer is available.
+ *
+ * If rect is not NULL, the caller promises to modify only data in the area
+ * specified by rect. If rect is NULL, the caller may modify the contents of the
+ * entire buffer.
+ *
+ * The content of the buffer outside of the specified rect is NOT modified
+ * by this call.
+ *
+ * The buffer usage may only specify AHARDWAREBUFFER_USAGE0_CPU_*. If set, then
+ * outVirtualAddress is filled with the address of the buffer in virtual memory,
+ * otherwise this function will fail.
+ *
+ * THREADING CONSIDERATIONS:
+ *
+ * It is legal for several different threads to lock a buffer for read access;
+ * none of the threads are blocked.
+ *
+ * Locking a buffer simultaneously for write or read/write is undefined, but
+ * will neither terminate the process nor block the caller; AHardwareBuffer_lock
+ * may return an error or leave the buffer's content into an indeterminate
+ * state.
+ *
+ * Returns NO_ERROR on success, BAD_VALUE if the buffer is NULL or if the usage0
+ * flags are not a combination of AHARDWAREBUFFER_USAGE0_CPU_*, or an error
+ * number of the lock fails for any reason.
+ */
+int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage0,
+ int32_t fence, const ARect* rect, void** outVirtualAddress);
+
+/*
+ * Unlock the AHardwareBuffer; must be called after all changes to the buffer
+ * are completed by the caller. If fence is not NULL then it will be set to a
+ * file descriptor that is signaled when all pending work on the buffer is
+ * completed. The caller is responsible for closing the fence when it is no
+ * longer needed.
+ *
+ * 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_unlock(AHardwareBuffer* buffer, int32_t* fence);
+
+/*
+ * Send the AHardwareBuffer to an AF_UNIX socket.
+ *
+ * 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);
+
+/*
+ * Receive the AHardwareBuffer from an AF_UNIX socket.
+ *
+ * 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);
+
+// ----------------------------------------------------------------------------
+// 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);
+
+__END_DECLS
+
+#endif // ANDROID_HARDWARE_BUFFER_H
diff --git a/libs/nativewindow/include/android/native_window.h b/libs/nativewindow/include/android/native_window.h
new file mode 100644
index 0000000..6a46d7f
--- /dev/null
+++ b/libs/nativewindow/include/android/native_window.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+/**
+ * @addtogroup NativeActivity Native Activity
+ * @{
+ */
+
+/**
+ * @file native_window.h
+ */
+
+#ifndef ANDROID_NATIVE_WINDOW_H
+#define ANDROID_NATIVE_WINDOW_H
+
+#include <sys/cdefs.h>
+
+#include <android/hardware_buffer.h>
+#include <android/rect.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Legacy window pixel format names, kept for backwards compatibility.
+ * New code and APIs should use AHARDWAREBUFFER_FORMAT_*.
+ */
+enum {
+ // NOTE: these values must match the values from graphics/common/x.x/types.hal
+
+ /** Red: 8 bits, Green: 8 bits, Blue: 8 bits, Alpha: 8 bits. **/
+ WINDOW_FORMAT_RGBA_8888 = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
+ /** Red: 8 bits, Green: 8 bits, Blue: 8 bits, Unused: 8 bits. **/
+ WINDOW_FORMAT_RGBX_8888 = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
+ /** Red: 5 bits, Green: 6 bits, Blue: 5 bits. **/
+ WINDOW_FORMAT_RGB_565 = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM,
+};
+
+struct ANativeWindow;
+/**
+ * {@link ANativeWindow} is opaque type that provides access to a native window.
+ *
+ * A pointer can be obtained using ANativeWindow_fromSurface().
+ */
+typedef struct ANativeWindow ANativeWindow;
+
+/**
+ * {@link ANativeWindow} is a struct that represents a windows buffer.
+ *
+ * A pointer can be obtained using ANativeWindow_lock().
+ */
+typedef struct ANativeWindow_Buffer {
+ // The number of pixels that are show horizontally.
+ int32_t width;
+
+ // The number of pixels that are shown vertically.
+ int32_t height;
+
+ // The number of *pixels* that a line in the buffer takes in
+ // memory. This may be >= width.
+ int32_t stride;
+
+ // The format of the buffer. One of WINDOW_FORMAT_*
+ int32_t format;
+
+ // The actual bits.
+ void* bits;
+
+ // Do not touch.
+ uint32_t reserved[6];
+} ANativeWindow_Buffer;
+
+/**
+ * Acquire a reference on the given ANativeWindow object. This prevents the object
+ * from being deleted until the reference is removed.
+ */
+void ANativeWindow_acquire(ANativeWindow* window);
+
+/**
+ * Remove a reference that was previously acquired with ANativeWindow_acquire().
+ */
+void ANativeWindow_release(ANativeWindow* window);
+
+/**
+ * Return the current width in pixels of the window surface. Returns a
+ * negative value on error.
+ */
+int32_t ANativeWindow_getWidth(ANativeWindow* window);
+
+/**
+ * Return the current height in pixels of the window surface. Returns a
+ * negative value on error.
+ */
+int32_t ANativeWindow_getHeight(ANativeWindow* window);
+
+/**
+ * Return the current pixel format of the window surface. Returns a
+ * negative value on error.
+ */
+int32_t ANativeWindow_getFormat(ANativeWindow* window);
+
+/**
+ * Change the format and size of the window buffers.
+ *
+ * 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
+ * when compositing it to the screen.
+ *
+ * For all of these parameters, if 0 is supplied then the window's base
+ * value will come back in force.
+ *
+ * width and height must be either both zero or both non-zero.
+ *
+ */
+int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window,
+ int32_t width, int32_t height, int32_t format);
+
+/**
+ * Lock the window's next drawing surface for writing.
+ * inOutDirtyBounds is used as an in/out parameter, upon entering the
+ * function, it contains the dirty region, that is, the region the caller
+ * intends to redraw. When the function returns, inOutDirtyBounds is updated
+ * with the actual area the caller needs to redraw -- this region is often
+ * extended by ANativeWindow_lock.
+ */
+int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer,
+ ARect* inOutDirtyBounds);
+
+/**
+ * Unlock the window's drawing surface after previously locking it,
+ * posting the new buffer to the display.
+ */
+int32_t ANativeWindow_unlockAndPost(ANativeWindow* window);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // ANDROID_NATIVE_WINDOW_H
+
+/** @} */
diff --git a/libs/nativewindow/include/private/android/AHardwareBufferHelpers.h b/libs/nativewindow/include/private/android/AHardwareBufferHelpers.h
new file mode 100644
index 0000000..f138fa7
--- /dev/null
+++ b/libs/nativewindow/include/private/android/AHardwareBufferHelpers.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2017 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 ANDROID_PRIVATE_NATIVE_AHARDWARE_BUFFER_HELPERS_H
+#define ANDROID_PRIVATE_NATIVE_AHARDWARE_BUFFER_HELPERS_H
+
+/*
+ * This file contains utility functions related to AHardwareBuffer, mostly to convert
+ * to/from HAL formats.
+ *
+ * These are PRIVATE methods, so this file can NEVER appear in a public NDK header.
+ * They are used by higher level libraries such as core/jni.
+ */
+
+#include <stdint.h>
+
+struct AHardwareBuffer;
+
+namespace android {
+
+uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t format);
+
+uint32_t AHardwareBuffer_convertToPixelFormat(uint32_t format);
+
+void AHardwareBuffer_convertToGrallocUsageBits(uint64_t usage,
+ uint64_t* outProducerUsage, uint64_t* outConsumerUsage);
+
+uint64_t AHardwareBuffer_convertFromGrallocUsageBits(
+ uint64_t producerUsage, uint64_t consumerUsage);
+
+
+class GraphicBuffer;
+const GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(const AHardwareBuffer* buffer);
+GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(AHardwareBuffer* buffer);
+AHardwareBuffer* AHardwareBuffer_from_GraphicBuffer(GraphicBuffer* buffer);
+
+} // namespace android
+
+#endif // ANDROID_PRIVATE_NATIVE_AHARDWARE_BUFFER_HELPERS_H
diff --git a/libs/vr/libbufferhub/bufferhub_tests.cpp b/libs/vr/libbufferhub/bufferhub_tests.cpp
index 0b9e0cc..fa61c4a 100644
--- a/libs/vr/libbufferhub/bufferhub_tests.cpp
+++ b/libs/vr/libbufferhub/bufferhub_tests.cpp
@@ -1,4 +1,3 @@
-#include <android/native_window.h>
#include <gtest/gtest.h>
#include <private/dvr/buffer_hub_client.h>
diff --git a/libs/vr/libdisplay/Android.mk b/libs/vr/libdisplay/Android.mk
index f0e62df..6a9458c 100644
--- a/libs/vr/libdisplay/Android.mk
+++ b/libs/vr/libdisplay/Android.mk
@@ -46,7 +46,8 @@
libui \
libgui \
libhardware \
- libsync
+ libsync \
+ libnativewindow \
staticLibraries := \
libbufferhub \
diff --git a/libs/vr/libsensor/tests/sensor_app_tests.cpp b/libs/vr/libsensor/tests/sensor_app_tests.cpp
index 0f5bf00..64c9864 100644
--- a/libs/vr/libsensor/tests/sensor_app_tests.cpp
+++ b/libs/vr/libsensor/tests/sensor_app_tests.cpp
@@ -1,6 +1,7 @@
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <math.h>
+#include <inttypes.h>
#include <dvr/graphics.h>
#include <dvr/pose_client.h>
diff --git a/libs/vr/libvrflinger/Android.mk b/libs/vr/libvrflinger/Android.mk
index 1706f30..3450788 100644
--- a/libs/vr/libvrflinger/Android.mk
+++ b/libs/vr/libvrflinger/Android.mk
@@ -56,6 +56,7 @@
libcutils \
liblog \
libhardware \
+ libnativewindow \
libutils \
libEGL \
libGLESv1_CM \