Bug 1239152 Memset RGBX surfaces to opaque white. r=nical

This commit is contained in:
Mason Chang 2016-02-17 07:34:37 -08:00
parent a6f8a6438e
commit a2b1f4d3fb
6 changed files with 51 additions and 11 deletions

View File

@ -909,13 +909,35 @@ DrawTargetSkia::InitWithGrContext(GrContext* aGrContext,
#endif
#ifdef DEBUG
bool
VerifyRGBXFormat(uint8_t* aData, const IntSize &aSize, const int32_t aStride, SurfaceFormat aFormat)
{
// We should've initialized the data to be opaque already
// On debug builds, verify that this is actually true.
int height = aSize.height;
int width = aSize.width;
for (int row = 0; row < height; ++row) {
for (int column = 0; column < width; column += 4) {
#ifdef IS_BIG_ENDIAN
MOZ_ASSERT(aData[column] == 0xFF);
#else
MOZ_ASSERT(aData[column + 3] == 0xFF);
#endif
}
aData += aStride;
}
return true;
}
#endif
void
DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat)
{
if (aFormat == SurfaceFormat::B8G8R8X8) {
// We have to manually set the A channel to be 255 as Skia doesn't understand BGRX
ConvertBGRXToBGRA(aData, aSize, aStride);
}
MOZ_ASSERT((aFormat != SurfaceFormat::B8G8R8X8) ||
VerifyRGBXFormat(aData, aSize, aStride, aFormat));
SkBitmap bitmap;
bitmap.setInfo(MakeSkiaImageInfo(aSize, aFormat), aStride);

View File

@ -369,9 +369,11 @@ static bool InitBuffer(uint8_t* buf, size_t bufSize, TextureAllocationFlags aAll
return false;
}
if (aAllocFlags & ALLOC_CLEAR_BUFFER) {
if ((aAllocFlags & ALLOC_CLEAR_BUFFER) ||
(aAllocFlags & ALLOC_CLEAR_BUFFER_BLACK)) {
memset(buf, 0, bufSize);
}
if (aAllocFlags & ALLOC_CLEAR_BUFFER_WHITE) {
memset(buf, 0xFF, bufSize);
}

View File

@ -290,10 +290,15 @@ void
ContentClientRemoteBuffer::CreateBackBuffer(const IntRect& aBufferRect)
{
// gfx::BackendType::NONE means fallback to the content backend
TextureAllocationFlags textureAllocFlags
= (mTextureFlags & TextureFlags::COMPONENT_ALPHA) ?
TextureAllocationFlags::ALLOC_CLEAR_BUFFER_BLACK :
TextureAllocationFlags::ALLOC_CLEAR_BUFFER;
mTextureClient = CreateTextureClientForDrawing(
mSurfaceFormat, mSize, BackendSelector::Content,
mTextureFlags | ExtraTextureFlags(),
TextureAllocationFlags::ALLOC_CLEAR_BUFFER
textureAllocFlags
);
if (!mTextureClient || !AddTextureClient(mTextureClient)) {
AbortTextureClientCreation();

View File

@ -833,6 +833,13 @@ TextureClient::CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
return nullptr;
}
if (aFormat == SurfaceFormat::B8G8R8X8 &&
(aAllocFlags != TextureAllocationFlags::ALLOC_CLEAR_BUFFER_BLACK) &&
aMoz2DBackend == gfx::BackendType::SKIA) {
// skia requires alpha component of RGBX textures to be 255.
aAllocFlags = TextureAllocationFlags::ALLOC_CLEAR_BUFFER_WHITE;
}
TextureData* texData = BufferTextureData::Create(aSize, aFormat, aMoz2DBackend,
aTextureFlags, aAllocFlags,
aAllocator);

View File

@ -69,15 +69,16 @@ class KeepAlive;
*/
enum TextureAllocationFlags {
ALLOC_DEFAULT = 0x0,
ALLOC_CLEAR_BUFFER = 0x1,
ALLOC_CLEAR_BUFFER_WHITE = 0x2,
ALLOC_DISALLOW_BUFFERTEXTURECLIENT = 0x4,
ALLOC_DEFAULT = 0,
ALLOC_CLEAR_BUFFER = 1 << 1, // Clear the buffer to whatever is best for the draw target
ALLOC_CLEAR_BUFFER_WHITE = 1 << 2, // explicit all white
ALLOC_CLEAR_BUFFER_BLACK = 1 << 3, // explicit all black
ALLOC_DISALLOW_BUFFERTEXTURECLIENT = 1 << 4,
// Allocate the texture for out-of-band content updates. This is mostly for
// TextureClientD3D11, which may otherwise choose D3D10 or non-KeyedMutex
// surfaces when used on the main thread.
ALLOC_FOR_OUT_OF_BAND_CONTENT = 0x8
ALLOC_FOR_OUT_OF_BAND_CONTENT = 1 << 5,
};
#ifdef XP_WIN

View File

@ -99,6 +99,7 @@ nsShmImage::Create(const LayoutDeviceIntSize& aSize,
(shm->mImage->green_mask == 0xff00) &&
(shm->mImage->blue_mask == 0xff)) {
shm->mFormat = SurfaceFormat::B8G8R8A8;
memset(shm->mSegment->memory(), 0, size);
break;
}
goto unsupported;
@ -108,11 +109,13 @@ nsShmImage::Create(const LayoutDeviceIntSize& aSize,
(shm->mImage->green_mask == 0xff00) &&
(shm->mImage->blue_mask == 0xff)) {
shm->mFormat = SurfaceFormat::B8G8R8X8;
memset(shm->mSegment->memory(), 0xFF, size);
break;
}
goto unsupported;
case 16:
shm->mFormat = SurfaceFormat::R5G6B5_UINT16;
memset(shm->mSegment->memory(), 0, size);
break;
unsupported:
default: