Implement an Android NDK build of SwiftShader using the CMake files.
From the build directory, run:
cmake -DCMAKE_TOOLCHAIN_FILE=../build/android.toolchain.cmake ..
Everything compiles and links. unittests, vk-unittests and ReactorUnitTests are known to work.
A "rundroid.sh" script is provided to upload and run Android binaries.
This CL has contains the first draft of an NDK-based FrameBuffer implementation.
It stubs out the gralloc calls in Image (consequence: EGLImage likely won't work).
NOTE: a small CMake patch is necessary; hopefully we'll find a way around this or land it in
CMake:
diff cmake-3.10/Modules/Platform/Android/Determine-Compiler-NDK.cmake.bak cmake-3.10/Modules/Platform/Android/Determine-Compiler-NDK.cmake
231c231
< set(_ANDROID_TOOL_C_COMPILER_EXTERNAL_TOOLCHAIN ${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_NAME}/prebuilt/${_ANDROID_HOST_DIR})
---
> set(_ANDROID_TOOL_C_COMPILER_EXTERNAL_TOOLCHAIN ${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_LLVM_NAME}/prebuilt/${_ANDROID_HOST_DIR})
Bug: b/129942368
Change-Id: I107a2f719256b6477ad105054ca68c676c05ec5c
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/27869
Presubmit-Ready: Stephen White <senorblanco@chromium.org>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Stephen White <senorblanco@chromium.org>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Common/Debug.hpp b/src/Common/Debug.hpp
index 9758c3b..0c862d4 100644
--- a/src/Common/Debug.hpp
+++ b/src/Common/Debug.hpp
@@ -15,7 +15,7 @@
#ifndef Debug_hpp
#define Debug_hpp
-#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD)
+#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD) && !defined(ANDROID_NDK_BUILD)
#include "DebugAndroid.hpp"
#else
diff --git a/src/Main/FrameBufferAndroid.cpp b/src/Main/FrameBufferAndroid.cpp
index 0ae5f09..38247bf 100644
--- a/src/Main/FrameBufferAndroid.cpp
+++ b/src/Main/FrameBufferAndroid.cpp
@@ -14,12 +14,16 @@
#include "FrameBufferAndroid.hpp"
+#ifndef ANDROID_NDK_BUILD
#include "Common/GrallocAndroid.hpp"
-
#include <system/window.h>
+#else
+#include <android/native_window.h>
+#endif
namespace sw
{
+#if !defined(ANDROID_NDK_BUILD)
inline int dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer)
{
#if ANDROID_PLATFORM_SDK_VERSION > 16
@@ -46,18 +50,23 @@
return window->cancelBuffer(window, buffer);
#endif
}
+#endif // !defined(ANDROID_NDK_BUILD)
FrameBufferAndroid::FrameBufferAndroid(ANativeWindow* window, int width, int height)
: FrameBuffer(width, height, false, false),
nativeWindow(window), buffer(nullptr)
{
+#ifndef ANDROID_NDK_BUILD
nativeWindow->common.incRef(&nativeWindow->common);
native_window_set_usage(nativeWindow, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
+#endif
}
FrameBufferAndroid::~FrameBufferAndroid()
{
+#ifndef ANDROID_NDK_BUILD
nativeWindow->common.decRef(&nativeWindow->common);
+#endif
}
void FrameBufferAndroid::blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect)
@@ -72,17 +81,51 @@
unlock();
}
+#ifndef ANDROID_NDK_BUILD
queueBuffer(nativeWindow, buffer, -1);
+#endif
}
}
void *FrameBufferAndroid::lock()
{
+
+#if defined(ANDROID_NDK_BUILD)
+ ANativeWindow_Buffer surfaceBuffer;
+ if (ANativeWindow_lock(nativeWindow, &surfaceBuffer, nullptr) != 0) {
+ TRACE("%s failed to lock buffer %p", __FUNCTION__, buffer);
+ return nullptr;
+ }
+ framebuffer = surfaceBuffer.bits;
+
+ if((surfaceBuffer.width < width) || (surfaceBuffer.height < height))
+ {
+ TRACE("lock failed: buffer of %dx%d too small for window of %dx%d",
+ surfaceBuffer.width, surfaceBuffer.height, width, height);
+ return nullptr;
+ }
+
+ switch(surfaceBuffer.format)
+ {
+ case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM: format = FORMAT_A8B8G8R8; break;
+ case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM: format = FORMAT_X8B8G8R8; break;
+ case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
+ // Frame buffers are expected to have 16-bit or 32-bit colors, not 24-bit.
+ TRACE("Unsupported frame buffer format R8G8B8"); ASSERT(false);
+ format = FORMAT_R8G8B8; // Wrong component order.
+ break;
+ case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM: format = FORMAT_R5G6B5; break;
+ default:
+ TRACE("Unsupported frame buffer format %d", surfaceBuffer.format); ASSERT(false);
+ format = FORMAT_NULL;
+ break;
+ }
+ stride = surfaceBuffer.stride * Surface::bytes(format);
+#else // !defined(ANDROID_NDK_BUILD)
if(dequeueBuffer(nativeWindow, &buffer) != 0)
{
return nullptr;
}
-
if(GrallocModule::getInstance()->lock(buffer->handle,
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
0, 0, buffer->width, buffer->height, &framebuffer) != 0)
@@ -117,8 +160,9 @@
format = FORMAT_NULL;
break;
}
-
stride = buffer->stride * Surface::bytes(format);
+#endif // !defined(ANDROID_NDK_BUILD)
+
return framebuffer;
}
@@ -132,10 +176,14 @@
framebuffer = nullptr;
+#ifdef ANDROID_NDK_BUILD
+ ANativeWindow_unlockAndPost(nativeWindow);
+#else
if(GrallocModule::getInstance()->unlock(buffer->handle) != 0)
{
TRACE("%s: badness unlock failed", __FUNCTION__);
}
+#endif
}
}
diff --git a/src/OpenGL/common/Image.hpp b/src/OpenGL/common/Image.hpp
index 1a1dfd7..856283f 100644
--- a/src/OpenGL/common/Image.hpp
+++ b/src/OpenGL/common/Image.hpp
@@ -21,12 +21,12 @@
#include <GLES3/gl3.h>
#include <GLES2/gl2ext.h>
-#if defined(__ANDROID__)
+#if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
#include <system/window.h>
#include "../../Common/GrallocAndroid.hpp"
#endif
-#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD)
+#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD) && !defined(ANDROID_NDK_BUILD)
#include "../../Common/DebugAndroid.hpp"
#define LOGLOCK(fmt, ...) // TRACE(fmt " tid=%d", ##__VA_ARGS__, gettid())
#else
@@ -235,7 +235,7 @@
void loadStencilData(GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, GLenum format, GLenum type, const void *input, void *buffer);
};
-#ifdef __ANDROID__
+#if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
inline GLenum GLPixelFormatFromAndroid(int halFormat)
{
@@ -362,7 +362,7 @@
}
};
-#endif // __ANDROID__
+#endif // __ANDROID__ && !defined(ANDROID_NDK_BUILD)
}
diff --git a/src/OpenGL/common/debug.cpp b/src/OpenGL/common/debug.cpp
index 87f7ee2..b145555 100644
--- a/src/OpenGL/common/debug.cpp
+++ b/src/OpenGL/common/debug.cpp
@@ -17,6 +17,7 @@
#include "common/debug.h"
#ifdef __ANDROID__
+#if !defined(ANDROID_NDK_BUILD)
#include <utils/String8.h>
#if ANDROID_PLATFORM_SDK_VERSION < 27
#include <cutils/log.h>
@@ -26,13 +27,14 @@
#error "ANDROID_PLATFORM_SDK_VERSION is not defined"
#endif
#endif
+#endif
#include <stdio.h>
#include <stdarg.h>
namespace es
{
-#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD)
+#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD) && !defined(ANDROID_NDK_BUILD)
static void output(const char *format, va_list vararg)
{
ALOGI("%s", android::String8::formatV(format, vararg).string());
diff --git a/src/OpenGL/common/debug.h b/src/OpenGL/common/debug.h
index f7bd972..ce488a2 100644
--- a/src/OpenGL/common/debug.h
+++ b/src/OpenGL/common/debug.h
@@ -17,7 +17,7 @@
#ifndef COMMON_DEBUG_H_
#define COMMON_DEBUG_H_
-#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD)
+#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD) && !defined(ANDROID_NDK_BUILD)
#include "../../Common/DebugAndroid.hpp"
#else
#include <stdio.h>
diff --git a/src/OpenGL/compiler/ConstantUnion.h b/src/OpenGL/compiler/ConstantUnion.h
index 2a1eeed..8a5b773 100644
--- a/src/OpenGL/compiler/ConstantUnion.h
+++ b/src/OpenGL/compiler/ConstantUnion.h
@@ -15,7 +15,7 @@
#ifndef _CONSTANT_UNION_INCLUDED_
#define _CONSTANT_UNION_INCLUDED_
-#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD)
+#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD) && !defined(ANDROID_NDK_BUILD)
#include "../../Common/DebugAndroid.hpp"
#else
#include <assert.h>
diff --git a/src/OpenGL/compiler/SymbolTable.h b/src/OpenGL/compiler/SymbolTable.h
index 2aad529..7cf41be 100644
--- a/src/OpenGL/compiler/SymbolTable.h
+++ b/src/OpenGL/compiler/SymbolTable.h
@@ -38,7 +38,7 @@
// are tracked in the intermediate representation, not the symbol table.
//
-#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD)
+#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD) && !defined(ANDROID_NDK_BUILD)
#include "../../Common/DebugAndroid.hpp"
#else
#include <assert.h>
diff --git a/src/OpenGL/compiler/debug.h b/src/OpenGL/compiler/debug.h
index ffeecaa..1bf999c 100644
--- a/src/OpenGL/compiler/debug.h
+++ b/src/OpenGL/compiler/debug.h
@@ -17,7 +17,7 @@
#ifndef COMPILER_DEBUG_H_
#define COMPILER_DEBUG_H_
-#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD)
+#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD) && !defined(ANDROID_NDK_BUILD)
#include "../../Common/DebugAndroid.hpp"
#define Trace(...) ((void)0)
diff --git a/src/OpenGL/libEGL/Config.cpp b/src/OpenGL/libEGL/Config.cpp
index 4c35f6b..1af9229 100644
--- a/src/OpenGL/libEGL/Config.cpp
+++ b/src/OpenGL/libEGL/Config.cpp
@@ -21,7 +21,7 @@
#include "common/debug.h"
#include <EGL/eglext.h>
-#ifdef __ANDROID__
+#if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
#include <system/graphics.h>
#endif
@@ -65,7 +65,7 @@
mBlueSize = 8;
mAlphaSize = 8;
mBindToTextureRGBA = EGL_TRUE;
- #ifdef __ANDROID__
+ #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
mNativeVisualID = HAL_PIXEL_FORMAT_BGRA_8888;
#else
mNativeVisualID = 2; // Arbitrary; prefer over ABGR
@@ -77,7 +77,7 @@
mBlueSize = 8;
mAlphaSize = 8;
mBindToTextureRGBA = EGL_TRUE;
- #ifdef __ANDROID__
+ #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
mNativeVisualID = HAL_PIXEL_FORMAT_RGBA_8888;
#endif
break;
@@ -86,7 +86,7 @@
mGreenSize = 6;
mBlueSize = 5;
mAlphaSize = 0;
- #ifdef __ANDROID__
+ #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
mNativeVisualID = HAL_PIXEL_FORMAT_RGB_565;
#endif
break;
@@ -96,7 +96,7 @@
mBlueSize = 8;
mAlphaSize = 0;
mBindToTextureRGB = EGL_TRUE;
- #ifdef __ANDROID__
+ #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
mNativeVisualID = 0x1FF; // HAL_PIXEL_FORMAT_BGRX_8888
#else
mNativeVisualID = 1; // Arbitrary; prefer over XBGR
@@ -108,7 +108,7 @@
mBlueSize = 8;
mAlphaSize = 0;
mBindToTextureRGB = EGL_TRUE;
- #ifdef __ANDROID__
+ #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
mNativeVisualID = HAL_PIXEL_FORMAT_RGBX_8888;
#endif
break;
diff --git a/src/OpenGL/libEGL/Display.cpp b/src/OpenGL/libEGL/Display.cpp
index ac525f0..99503ea 100644
--- a/src/OpenGL/libEGL/Display.cpp
+++ b/src/OpenGL/libEGL/Display.cpp
@@ -25,7 +25,7 @@
#include "common/debug.h"
#include "Common/RecursiveLock.hpp"
-#ifdef __ANDROID__
+#if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
#include <system/window.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
@@ -671,11 +671,13 @@
ERR("%s called with window==NULL %s:%d", __FUNCTION__, __FILE__, __LINE__);
return false;
}
+ #if !defined(ANDROID_NDK_BUILD)
if(static_cast<ANativeWindow*>(window)->common.magic != ANDROID_NATIVE_WINDOW_MAGIC)
{
ERR("%s called with window==%p bad magic %s:%d", __FUNCTION__, window, __FILE__, __LINE__);
return false;
}
+ #endif // !defined(ANDROID_NDK_BUILD)
return true;
#elif defined(USE_X11)
if(nativeDisplay)
@@ -782,6 +784,7 @@
default: UNREACHABLE(bpp); // Unexpected display mode color depth
}
#elif defined(__ANDROID__)
+ #if !defined(ANDROID_NDK_BUILD)
static const char *const framebuffer[] =
{
"/dev/graphics/fb0",
@@ -841,6 +844,7 @@
}
}
}
+ #endif // !defined_ANDROID_NDK_BUILD)
// No framebuffer device found, or we're in user space
return sw::FORMAT_X8B8G8R8;
diff --git a/src/OpenGL/libEGL/Surface.cpp b/src/OpenGL/libEGL/Surface.cpp
index b8bba5f..dd912ed 100644
--- a/src/OpenGL/libEGL/Surface.cpp
+++ b/src/OpenGL/libEGL/Surface.cpp
@@ -33,6 +33,9 @@
#elif defined(__APPLE__)
#include "OSXUtils.hpp"
#endif
+#if defined(__ANDROID__) && defined(ANDROID_NDK_BUILD)
+#include <android/native_window.h>
+#endif
#include <algorithm>
@@ -339,8 +342,13 @@
int windowWidth = client.right - client.left;
int windowHeight = client.bottom - client.top;
#elif defined(__ANDROID__)
+ #ifdef ANDROID_NDK_BUILD
+ int windowWidth = ANativeWindow_getWidth(window);
+ int windowHeight = ANativeWindow_getHeight(window);
+ #else
int windowWidth; window->query(window, NATIVE_WINDOW_WIDTH, &windowWidth);
int windowHeight; window->query(window, NATIVE_WINDOW_HEIGHT, &windowHeight);
+ #endif
#elif defined(USE_X11)
XWindowAttributes windowAttributes;
Status status = libX11->XGetWindowAttributes((::Display*)display->getNativeDisplay(), window, &windowAttributes);
diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp
index 912fe0c..51f5309 100644
--- a/src/OpenGL/libEGL/libEGL.cpp
+++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -23,7 +23,7 @@
#include "common/debug.h"
#include "Common/Version.h"
-#if defined(__ANDROID__)
+#if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
#include <system/window.h>
#elif defined(USE_X11)
#include "Main/libX11.hpp"
@@ -1170,7 +1170,7 @@
}
}
- #if defined(__ANDROID__)
+ #if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
if(target == EGL_NATIVE_BUFFER_ANDROID)
{
ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(buffer);
diff --git a/src/Reactor/Debug.hpp b/src/Reactor/Debug.hpp
index 720b38a..9df0b38 100644
--- a/src/Reactor/Debug.hpp
+++ b/src/Reactor/Debug.hpp
@@ -15,7 +15,7 @@
#ifndef Debug_hpp
#define Debug_hpp
-#ifdef __ANDROID__
+#if defined(__ANDROID__) && !defined(ANDROID_NDK_BUILD)
#include "DebugAndroid.hpp"
#else
diff --git a/src/System/Debug.hpp b/src/System/Debug.hpp
index 9758c3b..0c862d4 100644
--- a/src/System/Debug.hpp
+++ b/src/System/Debug.hpp
@@ -15,7 +15,7 @@
#ifndef Debug_hpp
#define Debug_hpp
-#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD)
+#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD) && !defined(ANDROID_NDK_BUILD)
#include "DebugAndroid.hpp"
#else