Commit 4e0d6f60 by Nicolas Capens

Implement support for RGBA display formats.

Change-Id: I5d9c9567d6885a2c3bbaf78a821f66f99b1bfcfe Reviewed-on: https://swiftshader-review.googlesource.com/2750Reviewed-by: 's avatarPing-Hao Wu <pinghao@google.com> Reviewed-by: 's avatarGreg Hartman <ghartman@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com> Tested-by: 's avatarNicolas Capens <capn@google.com>
parent f52c8ed1
...@@ -275,7 +275,7 @@ namespace sw ...@@ -275,7 +275,7 @@ namespace sw
} }
#endif #endif
if(state.destFormat == FORMAT_X8R8G8B8) if(state.destFormat == FORMAT_X8R8G8B8 || state.destFormat == FORMAT_A8R8G8B8)
{ {
Int x = x0; Int x = x0;
...@@ -289,6 +289,20 @@ namespace sw ...@@ -289,6 +289,20 @@ namespace sw
d += 4 * dBytes; 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) else if(state.sourceFormat == FORMAT_A16B16G16R16)
{ {
For(, x < width - 1, x += 2) For(, x < width - 1, x += 2)
...@@ -310,6 +324,14 @@ namespace sw ...@@ -310,6 +324,14 @@ namespace sw
{ {
*Pointer<Int>(d) = *Pointer<Int>(s); *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) else if(state.sourceFormat == FORMAT_A16B16G16R16)
{ {
UShort4 c = As<UShort4>(Swizzle(*Pointer<Short4>(s), 0xC6)) >> 8; UShort4 c = As<UShort4>(Swizzle(*Pointer<Short4>(s), 0xC6)) >> 8;
...@@ -322,6 +344,74 @@ namespace sw ...@@ -322,6 +344,74 @@ namespace sw
d += dBytes; 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) else if(state.destFormat == FORMAT_R8G8B8)
{ {
For(Int x = x0, x < width, x++) For(Int x = x0, x < width, x++)
...@@ -332,6 +422,12 @@ namespace sw ...@@ -332,6 +422,12 @@ namespace sw
*Pointer<Byte>(d + 1) = *Pointer<Byte>(s + 1); *Pointer<Byte>(d + 1) = *Pointer<Byte>(s + 1);
*Pointer<Byte>(d + 2) = *Pointer<Byte>(s + 2); *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) else if(state.sourceFormat == FORMAT_A16B16G16R16)
{ {
*Pointer<Byte>(d + 0) = *Pointer<Byte>(s + 5); *Pointer<Byte>(d + 0) = *Pointer<Byte>(s + 5);
...@@ -348,24 +444,33 @@ namespace sw ...@@ -348,24 +444,33 @@ namespace sw
{ {
For(Int x = x0, x < width, x++) For(Int x = x0, x < width, x++)
{ {
Int c;
if(state.sourceFormat == FORMAT_X8R8G8B8 || state.sourceFormat == FORMAT_A8R8G8B8) 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) 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); else ASSERT(false);
*Pointer<Short>(d) = Short((c & 0x00F80000) >> 8 |
(c & 0x0000FC00) >> 5 |
(c & 0x000000F8) >> 3);
s += sBytes; s += sBytes;
d += dBytes; d += dBytes;
} }
...@@ -450,6 +555,10 @@ namespace sw ...@@ -450,6 +555,10 @@ namespace sw
{ {
c2 = UnpackLow(As<Byte8>(c2), *Pointer<Byte8>(s)); 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) else if(state.sourceFormat == FORMAT_A16B16G16R16)
{ {
c2 = Swizzle(*Pointer<Short4>(s + 0), 0xC6); c2 = Swizzle(*Pointer<Short4>(s + 0), 0xC6);
...@@ -466,15 +575,19 @@ namespace sw ...@@ -466,15 +575,19 @@ namespace sw
c1 = c1 + c2; c1 = c1 + c2;
c1 = c1 + c1; c1 = c1 + c1;
c1 = As<Short4>(Pack(As<UShort4>(c1), As<UShort4>(c1))); if(state.destFormat == FORMAT_X8R8G8B8 || state.destFormat == FORMAT_A8R8G8B8)
{
if(state.destFormat == FORMAT_X8R8G8B8) *Pointer<UInt>(d) = UInt(As<Long>(Pack(As<UShort4>(c1), As<UShort4>(c1))));
}
else if(state.destFormat == FORMAT_X8B8G8R8 || state.destFormat == FORMAT_A8B8G8R8)
{ {
*Pointer<UInt>(d) = UInt(As<Long>(c1)); c1 = Swizzle(c1, 0xC6);
*Pointer<UInt>(d) = UInt(As<Long>(Pack(As<UShort4>(c1), As<UShort4>(c1))));
} }
else if(state.destFormat == FORMAT_R8G8B8) 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 + 0) = Byte(c >> 0);
*Pointer<Byte>(d + 1) = Byte(c >> 8); *Pointer<Byte>(d + 1) = Byte(c >> 8);
...@@ -482,7 +595,7 @@ namespace sw ...@@ -482,7 +595,7 @@ namespace sw
} }
else if(state.destFormat == FORMAT_R5G6B5) 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 | *Pointer<Short>(d) = Short((c & 0x00F80000) >> 8 |
(c & 0x0000FC00) >> 5 | (c & 0x0000FC00) >> 5 |
......
...@@ -7,7 +7,7 @@ namespace sw ...@@ -7,7 +7,7 @@ namespace sw
{ {
FrameBufferAndroid::FrameBufferAndroid(ANativeWindow* window, int width, int height) FrameBufferAndroid::FrameBufferAndroid(ANativeWindow* window, int width, int height)
: FrameBuffer(width, height, false, false), : 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_module_t const* pModule;
hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule); hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule);
...@@ -33,9 +33,9 @@ namespace sw ...@@ -33,9 +33,9 @@ namespace sw
copy(source, format); copy(source, format);
nativeWindow->queueBuffer(nativeWindow, buffer, -1); nativeWindow->queueBuffer(nativeWindow, buffer, -1);
if (buffer && bits) if (buffer && locked)
{ {
bits = 0; locked = 0;
unlock(buffer); unlock(buffer);
} }
...@@ -59,14 +59,21 @@ namespace sw ...@@ -59,14 +59,21 @@ namespace sw
buffer->common.incRef(&buffer->common); 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); ALOGE("connect() failed to lock buffer %p", buffer);
return NULL; return NULL;
} }
locked = bits; switch(buffer->format)
stride = buffer->stride; {
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; return locked;
} }
......
...@@ -31,7 +31,6 @@ namespace sw ...@@ -31,7 +31,6 @@ namespace sw
ANativeWindow* nativeWindow; ANativeWindow* nativeWindow;
ANativeWindowBuffer* buffer; ANativeWindowBuffer* buffer;
gralloc_module_t const* gralloc; gralloc_module_t const* gralloc;
void* bits;
}; };
} }
......
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