Bug 1257939 - initialize BGRX alpha channel to opaque when clearing and ignore uninitialized alpha in texture clients. r=mchang

This commit is contained in:
Lee Salzman 2016-03-18 16:58:55 -04:00
parent 5dde20a3f8
commit 7f2b998fc6
6 changed files with 20 additions and 19 deletions

View File

@ -1255,7 +1255,7 @@ public:
CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT); CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT);
static already_AddRefed<DrawTarget> static already_AddRefed<DrawTarget>
CreateDrawTargetForData(BackendType aBackend, unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat); CreateDrawTargetForData(BackendType aBackend, unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat, bool aUninitialized = false);
static already_AddRefed<ScaledFont> static already_AddRefed<ScaledFont>
CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize); CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize);

View File

@ -940,10 +940,10 @@ VerifyRGBXFormat(uint8_t* aData, const IntSize &aSize, const int32_t aStride, Su
#endif #endif
void void
DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat) DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat, bool aUninitialized)
{ {
MOZ_ASSERT((aFormat != SurfaceFormat::B8G8R8X8) || MOZ_ASSERT((aFormat != SurfaceFormat::B8G8R8X8) ||
VerifyRGBXFormat(aData, aSize, aStride, aFormat)); aUninitialized || VerifyRGBXFormat(aData, aSize, aStride, aFormat));
SkBitmap bitmap; SkBitmap bitmap;
bitmap.setInfo(MakeSkiaImageInfo(aSize, aFormat), aStride); bitmap.setInfo(MakeSkiaImageInfo(aSize, aFormat), aStride);

View File

@ -111,7 +111,7 @@ public:
virtual void *GetNativeSurface(NativeSurfaceType aType) override; virtual void *GetNativeSurface(NativeSurfaceType aType) override;
bool Init(const IntSize &aSize, SurfaceFormat aFormat); bool Init(const IntSize &aSize, SurfaceFormat aFormat);
void Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat); void Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat, bool aUninitialized = false);
#ifdef USE_SKIA_GPU #ifdef USE_SKIA_GPU
bool InitWithGrContext(GrContext* aGrContext, bool InitWithGrContext(GrContext* aGrContext,

View File

@ -384,7 +384,8 @@ Factory::CreateDrawTargetForData(BackendType aBackend,
unsigned char *aData, unsigned char *aData,
const IntSize &aSize, const IntSize &aSize,
int32_t aStride, int32_t aStride,
SurfaceFormat aFormat) SurfaceFormat aFormat,
bool aUninitialized)
{ {
MOZ_ASSERT(aData); MOZ_ASSERT(aData);
if (!AllowedSurfaceSize(aSize)) { if (!AllowedSurfaceSize(aSize)) {
@ -400,7 +401,7 @@ Factory::CreateDrawTargetForData(BackendType aBackend,
{ {
RefPtr<DrawTargetSkia> newTarget; RefPtr<DrawTargetSkia> newTarget;
newTarget = new DrawTargetSkia(); newTarget = new DrawTargetSkia();
newTarget->Init(aData, aSize, aStride, aFormat); newTarget->Init(aData, aSize, aStride, aFormat, aUninitialized);
retVal = newTarget; retVal = newTarget;
break; break;
} }

View File

@ -10,6 +10,7 @@
#include "mozilla/gfx/Logging.h" #include "mozilla/gfx/Logging.h"
#include "mozilla/gfx/2D.h" #include "mozilla/gfx/2D.h"
#include "mozilla/fallible.h" #include "mozilla/fallible.h"
#include <algorithm>
#ifdef MOZ_WIDGET_GTK #ifdef MOZ_WIDGET_GTK
#include "gfxPlatformGtk.h" #include "gfxPlatformGtk.h"
@ -245,7 +246,7 @@ BufferTextureData::BorrowDrawTarget()
uint32_t stride = ImageDataSerializer::GetRGBStride(rgb); uint32_t stride = ImageDataSerializer::GetRGBStride(rgb);
mDrawTarget = gfx::Factory::CreateDrawTargetForData(mMoz2DBackend, mDrawTarget = gfx::Factory::CreateDrawTargetForData(mMoz2DBackend,
GetBuffer(), rgb.size(), GetBuffer(), rgb.size(),
stride, rgb.format()); stride, rgb.format(), true);
if (mDrawTarget) { if (mDrawTarget) {
RefPtr<gfx::DrawTarget> dt = mDrawTarget; RefPtr<gfx::DrawTarget> dt = mDrawTarget;
@ -257,7 +258,7 @@ BufferTextureData::BorrowDrawTarget()
if (mMoz2DBackend != gfx::BackendType::CAIRO) { if (mMoz2DBackend != gfx::BackendType::CAIRO) {
mDrawTarget = gfx::Factory::CreateDrawTargetForData(gfx::BackendType::CAIRO, mDrawTarget = gfx::Factory::CreateDrawTargetForData(gfx::BackendType::CAIRO,
GetBuffer(), rgb.size(), GetBuffer(), rgb.size(),
stride, rgb.format()); stride, rgb.format(), true);
} }
if (!mDrawTarget) { if (!mDrawTarget) {
@ -397,7 +398,7 @@ MemoryTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
return true; return true;
} }
static bool InitBuffer(uint8_t* buf, size_t bufSize, TextureAllocationFlags aAllocFlags) static bool InitBuffer(uint8_t* buf, size_t bufSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aAllocFlags)
{ {
if (!buf) { if (!buf) {
gfxDebug() << "BufferTextureData: Failed to allocate " << bufSize << " bytes"; gfxDebug() << "BufferTextureData: Failed to allocate " << bufSize << " bytes";
@ -406,7 +407,13 @@ static bool InitBuffer(uint8_t* buf, size_t bufSize, TextureAllocationFlags aAll
if ((aAllocFlags & ALLOC_CLEAR_BUFFER) || if ((aAllocFlags & ALLOC_CLEAR_BUFFER) ||
(aAllocFlags & ALLOC_CLEAR_BUFFER_BLACK)) { (aAllocFlags & ALLOC_CLEAR_BUFFER_BLACK)) {
memset(buf, 0, bufSize); if (aFormat == gfx::SurfaceFormat::B8G8R8X8) {
// Even though BGRX was requested, XRGB_UINT32 is what is meant,
// so use 0xFF000000 to put alpha in the right place.
std::fill_n(reinterpret_cast<uint32_t*>(buf), bufSize / sizeof(uint32_t), 0xFF000000);
} else {
memset(buf, 0, bufSize);
}
} }
if (aAllocFlags & ALLOC_CLEAR_BUFFER_WHITE) { if (aAllocFlags & ALLOC_CLEAR_BUFFER_WHITE) {
@ -436,7 +443,7 @@ MemoryTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
} }
uint8_t* buf = new (fallible) uint8_t[bufSize]; uint8_t* buf = new (fallible) uint8_t[bufSize];
if (!InitBuffer(buf, bufSize, aAllocFlags)) { if (!InitBuffer(buf, bufSize, aFormat, aAllocFlags)) {
return nullptr; return nullptr;
} }
@ -513,7 +520,7 @@ ShmemTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
} }
uint8_t* buf = shm.get<uint8_t>(); uint8_t* buf = shm.get<uint8_t>();
if (!InitBuffer(buf, bufSize, aAllocFlags)) { if (!InitBuffer(buf, bufSize, aFormat, aAllocFlags)) {
return nullptr; return nullptr;
} }

View File

@ -852,13 +852,6 @@ TextureClient::CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
return nullptr; 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, TextureData* texData = BufferTextureData::Create(aSize, aFormat, aMoz2DBackend,
aTextureFlags, aAllocFlags, aTextureFlags, aAllocFlags,
aAllocator); aAllocator);