Implement support for RGBA display formats. Change-Id: I5d9c9567d6885a2c3bbaf78a821f66f99b1bfcfe Reviewed-on: https://swiftshader-review.googlesource.com/2750 Reviewed-by: Ping-Hao Wu <pinghao@google.com> Reviewed-by: Greg Hartman <ghartman@google.com> Reviewed-by: Nicolas Capens <capn@google.com> Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/Main/FrameBuffer.cpp b/src/Main/FrameBuffer.cpp index d1e74d0..d0216a8 100644 --- a/src/Main/FrameBuffer.cpp +++ b/src/Main/FrameBuffer.cpp
@@ -275,7 +275,7 @@ } #endif - if(state.destFormat == FORMAT_X8R8G8B8) + if(state.destFormat == FORMAT_X8R8G8B8 || state.destFormat == FORMAT_A8R8G8B8) { Int x = x0; @@ -289,6 +289,20 @@ d += 4 * dBytes; } } + else if(state.sourceFormat == FORMAT_X8B8G8R8 || state.sourceFormat == FORMAT_A8B8G8R8) + { + For(, x < width - 3, x += 4) + { + Int4 bgra = *Pointer<Int4>(s, width % 4 ? 1 : 16); + + *Pointer<Int4>(d, 1) = ((bgra & Int4(0x00FF0000)) >> 16) | + ((bgra & Int4(0x000000FF)) << 16) | + (bgra & Int4(0xFF00FF00)); + + s += 4 * sBytes; + d += 4 * dBytes; + } + } else if(state.sourceFormat == FORMAT_A16B16G16R16) { For(, x < width - 1, x += 2) @@ -310,6 +324,14 @@ { *Pointer<Int>(d) = *Pointer<Int>(s); } + else if(state.sourceFormat == FORMAT_X8B8G8R8 || state.sourceFormat == FORMAT_A8B8G8R8) + { + Int rgba = *Pointer<Int>(s); + + *Pointer<Int>(d) = ((rgba & Int(0x00FF0000)) >> 16) | + ((rgba & Int(0x000000FF)) << 16) | + (rgba & Int(0xFF00FF00)); + } else if(state.sourceFormat == FORMAT_A16B16G16R16) { UShort4 c = As<UShort4>(Swizzle(*Pointer<Short4>(s), 0xC6)) >> 8; @@ -322,6 +344,74 @@ d += dBytes; } } + else if(state.destFormat == FORMAT_X8B8G8R8 || state.destFormat == FORMAT_A8B8G8R8) + { + Int x = x0; + + if(state.sourceFormat == FORMAT_X8B8G8R8 || state.sourceFormat == FORMAT_A8B8G8R8) + { + For(, x < width - 3, x += 4) + { + *Pointer<Int4>(d, 1) = *Pointer<Int4>(s, width % 4 ? 1 : 16); + + s += 4 * sBytes; + d += 4 * dBytes; + } + } + else if(state.sourceFormat == FORMAT_X8R8G8B8 || state.sourceFormat == FORMAT_A8R8G8B8) + { + For(, x < width - 3, x += 4) + { + Int4 bgra = *Pointer<Int4>(s, width % 4 ? 1 : 16); + + *Pointer<Int4>(d, 1) = ((bgra & Int4(0x00FF0000)) >> 16) | + ((bgra & Int4(0x000000FF)) << 16) | + (bgra & Int4(0xFF00FF00)); + + s += 4 * sBytes; + d += 4 * dBytes; + } + } + else if(state.sourceFormat == FORMAT_A16B16G16R16) + { + For(, x < width - 1, x += 2) + { + UShort4 c0 = *Pointer<UShort4>(s + 0) >> 8; + UShort4 c1 = *Pointer<UShort4>(s + 8) >> 8; + + *Pointer<Int2>(d) = As<Int2>(Pack(c0, c1)); + + s += 2 * sBytes; + d += 2 * dBytes; + } + } + else ASSERT(false); + + For(, x < width, x++) + { + if(state.sourceFormat == FORMAT_X8B8G8R8 || state.sourceFormat == FORMAT_A8B8G8R8) + { + *Pointer<Int>(d) = *Pointer<Int>(s); + } + else if(state.sourceFormat == FORMAT_X8R8G8B8 || state.sourceFormat == FORMAT_A8R8G8B8) + { + Int bgra = *Pointer<Int>(s); + *Pointer<Int>(d) = ((bgra & Int(0x00FF0000)) >> 16) | + ((bgra & Int(0x000000FF)) << 16) | + (bgra & Int(0xFF00FF00)); + } + else if(state.sourceFormat == FORMAT_A16B16G16R16) + { + UShort4 c = *Pointer<UShort4>(s) >> 8; + + *Pointer<Int>(d) = Int(As<Int2>(Pack(c, c))); + } + else ASSERT(false); + + s += sBytes; + d += dBytes; + } + } else if(state.destFormat == FORMAT_R8G8B8) { For(Int x = x0, x < width, x++) @@ -332,6 +422,12 @@ *Pointer<Byte>(d + 1) = *Pointer<Byte>(s + 1); *Pointer<Byte>(d + 2) = *Pointer<Byte>(s + 2); } + else if(state.sourceFormat == FORMAT_X8B8G8R8 || state.sourceFormat == FORMAT_A8B8G8R8) + { + *Pointer<Byte>(d + 0) = *Pointer<Byte>(s + 2); + *Pointer<Byte>(d + 1) = *Pointer<Byte>(s + 1); + *Pointer<Byte>(d + 2) = *Pointer<Byte>(s + 0); + } else if(state.sourceFormat == FORMAT_A16B16G16R16) { *Pointer<Byte>(d + 0) = *Pointer<Byte>(s + 5); @@ -348,24 +444,33 @@ { For(Int x = x0, x < width, x++) { - Int c; - if(state.sourceFormat == FORMAT_X8R8G8B8 || state.sourceFormat == FORMAT_A8R8G8B8) { - c = *Pointer<Int>(s); + Int c = *Pointer<Int>(s); + + *Pointer<Short>(d) = Short((c & 0x00F80000) >> 8 | + (c & 0x0000FC00) >> 5 | + (c & 0x000000F8) >> 3); + } + else if(state.sourceFormat == FORMAT_X8B8G8R8 || state.sourceFormat == FORMAT_A8B8G8R8) + { + Int c = *Pointer<Int>(s); + + *Pointer<Short>(d) = Short((c & 0x00F80000) >> 19 | + (c & 0x0000FC00) >> 5 | + (c & 0x000000F8) << 8); } else if(state.sourceFormat == FORMAT_A16B16G16R16) { - UShort4 cc = As<UShort4>(Swizzle(*Pointer<Short4>(s + 0), 0xC6)) >> 8; + UShort4 cc = *Pointer<UShort4>(s) >> 8; + Int c = Int(As<Int2>(Pack(cc, cc))); - c = Int(As<Int2>(Pack(cc, cc))); + *Pointer<Short>(d) = Short((c & 0x00F80000) >> 19 | + (c & 0x0000FC00) >> 5 | + (c & 0x000000F8) << 8); } else ASSERT(false); - *Pointer<Short>(d) = Short((c & 0x00F80000) >> 8 | - (c & 0x0000FC00) >> 5 | - (c & 0x000000F8) >> 3); - s += sBytes; d += dBytes; } @@ -450,6 +555,10 @@ { c2 = UnpackLow(As<Byte8>(c2), *Pointer<Byte8>(s)); } + else if(state.sourceFormat == FORMAT_X8B8G8R8 || state.sourceFormat == FORMAT_A8B8G8R8) + { + c2 = Swizzle(UnpackLow(As<Byte8>(c2), *Pointer<Byte8>(s)), 0xC6); + } else if(state.sourceFormat == FORMAT_A16B16G16R16) { c2 = Swizzle(*Pointer<Short4>(s + 0), 0xC6); @@ -466,15 +575,19 @@ c1 = c1 + c2; c1 = c1 + c1; - c1 = As<Short4>(Pack(As<UShort4>(c1), As<UShort4>(c1))); - - if(state.destFormat == FORMAT_X8R8G8B8) + if(state.destFormat == FORMAT_X8R8G8B8 || state.destFormat == FORMAT_A8R8G8B8) { - *Pointer<UInt>(d) = UInt(As<Long>(c1)); + *Pointer<UInt>(d) = UInt(As<Long>(Pack(As<UShort4>(c1), As<UShort4>(c1)))); + } + else if(state.destFormat == FORMAT_X8B8G8R8 || state.destFormat == FORMAT_A8B8G8R8) + { + c1 = Swizzle(c1, 0xC6); + + *Pointer<UInt>(d) = UInt(As<Long>(Pack(As<UShort4>(c1), As<UShort4>(c1)))); } else if(state.destFormat == FORMAT_R8G8B8) { - Int c = Int(As<Int2>(c1)); + Int c = Int(As<Int2>(Pack(As<UShort4>(c1), As<UShort4>(c1)))); *Pointer<Byte>(d + 0) = Byte(c >> 0); *Pointer<Byte>(d + 1) = Byte(c >> 8); @@ -482,7 +595,7 @@ } else if(state.destFormat == FORMAT_R5G6B5) { - Int c = Int(As<Int2>(c1)); + Int c = Int(As<Int2>(Pack(As<UShort4>(c1), As<UShort4>(c1)))); *Pointer<Short>(d) = Short((c & 0x00F80000) >> 8 | (c & 0x0000FC00) >> 5 |
diff --git a/src/Main/FrameBufferAndroid.cpp b/src/Main/FrameBufferAndroid.cpp index 09dd2bd..03a54a4 100644 --- a/src/Main/FrameBufferAndroid.cpp +++ b/src/Main/FrameBufferAndroid.cpp
@@ -7,7 +7,7 @@ { FrameBufferAndroid::FrameBufferAndroid(ANativeWindow* window, int width, int height) : FrameBuffer(width, height, false, false), - nativeWindow(window), buffer(0), gralloc(0), bits(NULL) + nativeWindow(window), buffer(0), gralloc(0) { hw_module_t const* pModule; hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule); @@ -33,9 +33,9 @@ copy(source, format); nativeWindow->queueBuffer(nativeWindow, buffer, -1); - if (buffer && bits) + if (buffer && locked) { - bits = 0; + locked = 0; unlock(buffer); } @@ -59,14 +59,21 @@ buffer->common.incRef(&buffer->common); - if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != android::NO_ERROR) + if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, &locked) != android::NO_ERROR) { ALOGE("connect() failed to lock buffer %p", buffer); return NULL; } - locked = bits; - stride = buffer->stride; + switch(buffer->format) + { + default: ASSERT(false); + case HAL_PIXEL_FORMAT_RGBA_8888: destFormat = FORMAT_A8B8G8R8; break; + case HAL_PIXEL_FORMAT_RGBX_8888: destFormat = FORMAT_X8B8G8R8; break; + case HAL_PIXEL_FORMAT_BGRA_8888: destFormat = FORMAT_A8R8G8B8; break; + } + + stride = buffer->stride * Surface::bytes(destFormat); return locked; }
diff --git a/src/Main/FrameBufferAndroid.hpp b/src/Main/FrameBufferAndroid.hpp index e8a9c0c..b19e2ab 100644 --- a/src/Main/FrameBufferAndroid.hpp +++ b/src/Main/FrameBufferAndroid.hpp
@@ -31,7 +31,6 @@ ANativeWindow* nativeWindow; ANativeWindowBuffer* buffer; gralloc_module_t const* gralloc; - void* bits; }; }