Commit b508ff81 by Ping-Hao Wu Committed by Nicolas Capens

Implement basic ANDROID_image_native_buffer support.

Change-Id: I7e844eb7c313455d48cd2fc09440f10d639b4c77 Reviewed-on: https://swiftshader-review.googlesource.com/2758Tested-by: 's avatarNicolas Capens <capn@google.com> Reviewed-by: 's avatarGreg Hartman <ghartman@google.com> Reviewed-by: 's avatarPing-Hao Wu <pinghao@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 4e0d6f60
...@@ -3,6 +3,11 @@ ...@@ -3,6 +3,11 @@
#include "Renderer/Surface.hpp" #include "Renderer/Surface.hpp"
#if defined(__ANDROID__)
#include <hardware/gralloc.h>
#include <system/window.h>
#endif
#include <assert.h> #include <assert.h>
namespace egl namespace egl
...@@ -23,6 +28,11 @@ public: ...@@ -23,6 +28,11 @@ public:
, sw::Surface(resource, width, height, depth, internalFormat, true, true) , sw::Surface(resource, width, height, depth, internalFormat, true, true)
{ {
shared = false; shared = false;
#if defined(__ANDROID__)
nativeBuffer = 0;
gralloc = 0;
#endif
} }
Image(sw::Resource *resource, int width, int height, int depth, sw::Format internalFormat, bool lockable, bool renderTarget) Image(sw::Resource *resource, int width, int height, int depth, sw::Format internalFormat, bool lockable, bool renderTarget)
...@@ -30,6 +40,11 @@ public: ...@@ -30,6 +40,11 @@ public:
, sw::Surface(resource, width, height, depth, internalFormat, lockable, renderTarget) , sw::Surface(resource, width, height, depth, internalFormat, lockable, renderTarget)
{ {
shared = false; shared = false;
#if defined(__ANDROID__)
nativeBuffer = 0;
gralloc = 0;
#endif
} }
GLsizei getWidth() const GLsizei getWidth() const
...@@ -76,6 +91,13 @@ public: ...@@ -76,6 +91,13 @@ public:
void *lock(unsigned int left, unsigned int top, sw::Lock lock) void *lock(unsigned int left, unsigned int top, sw::Lock lock)
{ {
#if defined(__ANDROID__)
if(nativeBuffer) // Lock the buffer from ANativeWindowBuffer
{
return lockNativeBuffer(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
}
#endif
return lockExternal(left, top, 0, lock, sw::PUBLIC); return lockExternal(left, top, 0, lock, sw::PUBLIC);
} }
...@@ -86,6 +108,13 @@ public: ...@@ -86,6 +108,13 @@ public:
void unlock() void unlock()
{ {
#if defined(__ANDROID__)
if(nativeBuffer) // Unlock the buffer from ANativeWindowBuffer
{
return unlockNativeBuffer();
}
#endif
unlockExternal(); unlockExternal();
} }
...@@ -94,15 +123,48 @@ public: ...@@ -94,15 +123,48 @@ public:
virtual void unbind(const Texture *parent) = 0; // Break parent ownership and release virtual void unbind(const Texture *parent) = 0; // Break parent ownership and release
void destroyShared() // Release a shared image void destroyShared() // Release a shared image
{ {
#if defined(__ANDROID__)
if(nativeBuffer)
{
nativeBuffer->common.decRef(&nativeBuffer->common);
}
#endif
assert(shared); assert(shared);
shared = false; shared = false;
release(); release();
} }
virtual void loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input) = 0; virtual void loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input) = 0;
virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) = 0; virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) = 0;
#if defined(__ANDROID__)
void setNativeBuffer(ANativeWindowBuffer* buffer)
{
nativeBuffer = buffer;
nativeBuffer->common.incRef(&nativeBuffer->common);
}
virtual void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client)
{
if(nativeBuffer) // Lock the buffer from ANativeWindowBuffer
{
return lockNativeBuffer(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
}
return sw::Surface::lockInternal(x, y, z, lock, client);
}
virtual void unlockInternal()
{
if(nativeBuffer) // Unlock the buffer from ANativeWindowBuffer
{
return unlockNativeBuffer();
}
return sw::Surface::unlockInternal();
}
#endif
protected: protected:
virtual ~Image() virtual ~Image()
{ {
...@@ -116,6 +178,40 @@ protected: ...@@ -116,6 +178,40 @@ protected:
const int depth; const int depth;
bool shared; // Used as an EGLImage bool shared; // Used as an EGLImage
#if defined(__ANDROID__)
ANativeWindowBuffer *nativeBuffer;
gralloc_module_t const *gralloc;
void initGralloc()
{
hw_module_t const *module;
hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
gralloc = reinterpret_cast<gralloc_module_t const*>(module);
}
void* lockNativeBuffer(int usage)
{
if(!gralloc)
{
initGralloc();
}
void *buffer = 0;
gralloc->lock(gralloc, nativeBuffer->handle, usage, 0, 0, nativeBuffer->width, nativeBuffer->height, &buffer);
return buffer;
}
void unlockNativeBuffer()
{
if(!gralloc)
{
initGralloc();
}
gralloc->unlock(gralloc, nativeBuffer->handle);
}
#endif
}; };
} }
......
...@@ -20,6 +20,10 @@ ...@@ -20,6 +20,10 @@
#include "common/debug.h" #include "common/debug.h"
#include "Common/Version.h" #include "Common/Version.h"
#if defined(__ANDROID__)
#include <system/window.h>
#endif
#include <string.h> #include <string.h>
static bool validateDisplay(egl::Display *display) static bool validateDisplay(egl::Display *display)
...@@ -870,6 +874,15 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu ...@@ -870,6 +874,15 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
} }
#if defined(__ANDROID__)
if(target == EGL_NATIVE_BUFFER_ANDROID)
{
// When target is EGL_NATIVE_BUFFER_ANDROID, ctx is always EGL_NO_CONTEXT.
// Get the current context so that we can validate and create shared image
context = static_cast<egl::Context*>(egl::getCurrentContext());
}
#endif
EGLenum validationResult = context->validateSharedImage(target, name, textureLevel); EGLenum validationResult = context->validateSharedImage(target, name, textureLevel);
if(validationResult != EGL_SUCCESS) if(validationResult != EGL_SUCCESS)
......
...@@ -2561,6 +2561,10 @@ EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint texture ...@@ -2561,6 +2561,10 @@ EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint texture
break; break;
case EGL_GL_RENDERBUFFER_KHR: case EGL_GL_RENDERBUFFER_KHR:
break; break;
#if defined(__ANDROID__)
case EGL_NATIVE_BUFFER_ANDROID:
break;
#endif
default: default:
return EGL_BAD_PARAMETER; return EGL_BAD_PARAMETER;
} }
...@@ -2608,6 +2612,32 @@ EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint texture ...@@ -2608,6 +2612,32 @@ EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint texture
return EGL_BAD_ACCESS; return EGL_BAD_ACCESS;
} }
} }
#if defined(__ANDROID__)
else if(target == EGL_NATIVE_BUFFER_ANDROID)
{
ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name);
if(nativeBuffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
{
return EGL_BAD_PARAMETER;
}
if(nativeBuffer->common.version != sizeof(ANativeWindowBuffer))
{
return EGL_BAD_PARAMETER;
}
switch(nativeBuffer->format)
{
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_RGB_565:
break;
default:
return EGL_BAD_PARAMETER;
}
}
#endif
else UNREACHABLE(); else UNREACHABLE();
return EGL_SUCCESS; return EGL_SUCCESS;
...@@ -2627,6 +2657,22 @@ egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textu ...@@ -2627,6 +2657,22 @@ egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textu
return renderbuffer->createSharedImage(); return renderbuffer->createSharedImage();
} }
#if defined(__ANDROID__)
else if(target == EGL_NATIVE_BUFFER_ANDROID)
{
ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name);
nativeBuffer->common.incRef(&nativeBuffer->common);
GLenum format = Image::getColorFormatFromAndroid(nativeBuffer->format);
GLenum type = Image::getPixelFormatFromAndroid(nativeBuffer->format);
es1::Image *image = new Image(0, nativeBuffer->width, nativeBuffer->height, format, type);
image->setNativeBuffer(nativeBuffer);
image->markShared();
return image;
}
#endif
else UNREACHABLE(); else UNREACHABLE();
return 0; return 0;
......
...@@ -544,4 +544,46 @@ namespace es1 ...@@ -544,4 +544,46 @@ namespace es1
unlock(); unlock();
} }
}
\ No newline at end of file #if defined(__ANDROID__)
GLenum Image::getColorFormatFromAndroid(int format)
{
switch(format)
{
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
return GL_RGBA;
case HAL_PIXEL_FORMAT_RGB_888:
return GL_RGB;
case HAL_PIXEL_FORMAT_RGB_565:
return GL_RGB565_OES;
case HAL_PIXEL_FORMAT_BGRA_8888:
return GL_BGRA_EXT;
#if GCE_PLATFORM_SDK_VERSION >= 19
case HAL_PIXEL_FORMAT_sRGB_A_8888:
case HAL_PIXEL_FORMAT_sRGB_X_8888:
#endif
case HAL_PIXEL_FORMAT_YV12:
case HAL_PIXEL_FORMAT_Y8:
case HAL_PIXEL_FORMAT_Y16:
case HAL_PIXEL_FORMAT_RAW_SENSOR:
case HAL_PIXEL_FORMAT_BLOB:
case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
case HAL_PIXEL_FORMAT_YCbCr_420_888:
default:
UNIMPLEMENTED();
}
return GL_RGBA;
}
GLenum Image::getPixelFormatFromAndroid(int format)
{
if(format == HAL_PIXEL_FORMAT_Y16)
{
return GL_UNSIGNED_SHORT;
}
return GL_UNSIGNED_BYTE;
}
#endif
}
...@@ -37,6 +37,11 @@ namespace es1 ...@@ -37,6 +37,11 @@ namespace es1
static sw::Format selectInternalFormat(GLenum format, GLenum type); static sw::Format selectInternalFormat(GLenum format, GLenum type);
#if defined(__ANDROID__)
static GLenum getColorFormatFromAndroid(int format);
static GLenum getPixelFormatFromAndroid(int format);
#endif
private: private:
virtual ~Image(); virtual ~Image();
......
...@@ -3522,6 +3522,10 @@ EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint texture ...@@ -3522,6 +3522,10 @@ EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint texture
break; break;
case EGL_GL_RENDERBUFFER_KHR: case EGL_GL_RENDERBUFFER_KHR:
break; break;
#if defined(__ANDROID__)
case EGL_NATIVE_BUFFER_ANDROID:
break;
#endif
default: default:
return EGL_BAD_PARAMETER; return EGL_BAD_PARAMETER;
} }
...@@ -3569,6 +3573,32 @@ EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint texture ...@@ -3569,6 +3573,32 @@ EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint texture
return EGL_BAD_ACCESS; return EGL_BAD_ACCESS;
} }
} }
#if defined(__ANDROID__)
else if(target == EGL_NATIVE_BUFFER_ANDROID)
{
ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name);
if(nativeBuffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
{
return EGL_BAD_PARAMETER;
}
if(nativeBuffer->common.version != sizeof(ANativeWindowBuffer))
{
return EGL_BAD_PARAMETER;
}
switch(nativeBuffer->format)
{
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_RGB_565:
break;
default:
return EGL_BAD_PARAMETER;
}
}
#endif
else UNREACHABLE(); else UNREACHABLE();
return EGL_SUCCESS; return EGL_SUCCESS;
...@@ -3601,6 +3631,22 @@ egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textu ...@@ -3601,6 +3631,22 @@ egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textu
return renderbuffer->createSharedImage(); return renderbuffer->createSharedImage();
} }
#if defined(__ANDROID__)
else if(target == EGL_NATIVE_BUFFER_ANDROID)
{
ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name);
nativeBuffer->common.incRef(&nativeBuffer->common);
GLenum format = Image::getColorFormatFromAndroid(nativeBuffer->format);
GLenum type = Image::getPixelFormatFromAndroid(nativeBuffer->format);
es2::Image *image = new Image(0, nativeBuffer->width, nativeBuffer->height, format, type);
image->setNativeBuffer(nativeBuffer);
image->markShared();
return image;
}
#endif
else UNREACHABLE(); else UNREACHABLE();
return 0; return 0;
......
...@@ -53,13 +53,13 @@ namespace ...@@ -53,13 +53,13 @@ namespace
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
template<> template<>
void LoadImageRow<Alpha>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<Alpha>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
memcpy(dest + xoffset, source, width); memcpy(dest + xoffset, source, width);
} }
template<> template<>
void LoadImageRow<AlphaFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<AlphaFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const float *sourceF = reinterpret_cast<const float*>(source); const float *sourceF = reinterpret_cast<const float*>(source);
...@@ -74,7 +74,7 @@ namespace ...@@ -74,7 +74,7 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<AlphaHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<AlphaHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source); const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
...@@ -89,13 +89,13 @@ namespace ...@@ -89,13 +89,13 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<Luminance>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<Luminance>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
memcpy(dest + xoffset, source, width); memcpy(dest + xoffset, source, width);
} }
template<> template<>
void LoadImageRow<LuminanceFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<LuminanceFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const float *sourceF = reinterpret_cast<const float*>(source); const float *sourceF = reinterpret_cast<const float*>(source);
...@@ -110,7 +110,7 @@ namespace ...@@ -110,7 +110,7 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<LuminanceHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<LuminanceHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source); const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
...@@ -125,13 +125,13 @@ namespace ...@@ -125,13 +125,13 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<LuminanceAlpha>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<LuminanceAlpha>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
memcpy(dest + xoffset * 2, source, width * 2); memcpy(dest + xoffset * 2, source, width * 2);
} }
template<> template<>
void LoadImageRow<LuminanceAlphaFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<LuminanceAlphaFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const float *sourceF = reinterpret_cast<const float*>(source); const float *sourceF = reinterpret_cast<const float*>(source);
...@@ -146,7 +146,7 @@ namespace ...@@ -146,7 +146,7 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<LuminanceAlphaHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<LuminanceAlphaHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source); const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
...@@ -161,7 +161,7 @@ namespace ...@@ -161,7 +161,7 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<RGBUByte>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<RGBUByte>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
unsigned char *destB = dest + xoffset * 4; unsigned char *destB = dest + xoffset * 4;
...@@ -175,7 +175,7 @@ namespace ...@@ -175,7 +175,7 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<RGB565>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<RGB565>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const unsigned short *source565 = reinterpret_cast<const unsigned short*>(source); const unsigned short *source565 = reinterpret_cast<const unsigned short*>(source);
...@@ -191,7 +191,7 @@ namespace ...@@ -191,7 +191,7 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<RGBFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<RGBFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const float *sourceF = reinterpret_cast<const float*>(source); const float *sourceF = reinterpret_cast<const float*>(source);
...@@ -206,7 +206,7 @@ namespace ...@@ -206,7 +206,7 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<RGBHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<RGBHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source); const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
...@@ -221,7 +221,7 @@ namespace ...@@ -221,7 +221,7 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<RGBAUByte>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<RGBAUByte>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source); const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
...@@ -234,7 +234,7 @@ namespace ...@@ -234,7 +234,7 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<RGBA4444>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<RGBA4444>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const unsigned short *source4444 = reinterpret_cast<const unsigned short*>(source); const unsigned short *source4444 = reinterpret_cast<const unsigned short*>(source);
...@@ -250,7 +250,7 @@ namespace ...@@ -250,7 +250,7 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<RGBA5551>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<RGBA5551>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const unsigned short *source5551 = reinterpret_cast<const unsigned short*>(source); const unsigned short *source5551 = reinterpret_cast<const unsigned short*>(source);
...@@ -266,25 +266,25 @@ namespace ...@@ -266,25 +266,25 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<RGBAFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<RGBAFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
memcpy(dest + xoffset * 16, source, width * 16); memcpy(dest + xoffset * 16, source, width * 16);
} }
template<> template<>
void LoadImageRow<RGBAHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<RGBAHalfFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
memcpy(dest + xoffset * 8, source, width * 8); memcpy(dest + xoffset * 8, source, width * 8);
} }
template<> template<>
void LoadImageRow<BGRA>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<BGRA>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
memcpy(dest + xoffset * 4, source, width * 4); memcpy(dest + xoffset * 4, source, width * 4);
} }
template<> template<>
void LoadImageRow<D16>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<D16>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const unsigned short *sourceD16 = reinterpret_cast<const unsigned short*>(source); const unsigned short *sourceD16 = reinterpret_cast<const unsigned short*>(source);
...@@ -296,7 +296,7 @@ namespace ...@@ -296,7 +296,7 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<D24>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<D24>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const unsigned int *sourceD24 = reinterpret_cast<const unsigned int*>(source); const unsigned int *sourceD24 = reinterpret_cast<const unsigned int*>(source);
...@@ -308,7 +308,7 @@ namespace ...@@ -308,7 +308,7 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<D32>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<D32>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const unsigned int *sourceD32 = reinterpret_cast<const unsigned int*>(source); const unsigned int *sourceD32 = reinterpret_cast<const unsigned int*>(source);
...@@ -320,7 +320,7 @@ namespace ...@@ -320,7 +320,7 @@ namespace
} }
} }
template<> template<>
void LoadImageRow<S8>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width) void LoadImageRow<S8>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
{ {
const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source); const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
...@@ -670,4 +670,44 @@ namespace es2 ...@@ -670,4 +670,44 @@ namespace es2
unlock(); unlock();
} }
}
\ No newline at end of file #if defined(__ANDROID__)
GLenum Image::getColorFormatFromAndroid(int format)
{
switch(format)
{
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
return GL_RGBA;
case HAL_PIXEL_FORMAT_RGB_888:
return GL_RGB;
case HAL_PIXEL_FORMAT_RGB_565:
return GL_RGB565_OES;
case HAL_PIXEL_FORMAT_BGRA_8888:
return GL_BGRA_EXT;
case HAL_PIXEL_FORMAT_sRGB_A_8888:
case HAL_PIXEL_FORMAT_sRGB_X_8888:
case HAL_PIXEL_FORMAT_YV12:
case HAL_PIXEL_FORMAT_Y8:
case HAL_PIXEL_FORMAT_Y16:
case HAL_PIXEL_FORMAT_RAW_SENSOR:
case HAL_PIXEL_FORMAT_BLOB:
case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
case HAL_PIXEL_FORMAT_YCbCr_420_888:
default:
UNIMPLEMENTED();
}
return GL_RGBA;
}
GLenum Image::getPixelFormatFromAndroid(int format)
{
if(format == HAL_PIXEL_FORMAT_Y16)
{
return GL_UNSIGNED_SHORT;
}
return GL_UNSIGNED_BYTE;
}
#endif
}
...@@ -38,6 +38,11 @@ namespace es2 ...@@ -38,6 +38,11 @@ namespace es2
static sw::Format selectInternalFormat(GLenum format, GLenum type); static sw::Format selectInternalFormat(GLenum format, GLenum type);
#if defined(__ANDROID__)
static GLenum getColorFormatFromAndroid(int format);
static GLenum getPixelFormatFromAndroid(int format);
#endif
private: private:
virtual ~Image(); virtual ~Image();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment